In the iOS Foundations course, Lesson 09 Quiz asks:
Is the following JSON valid? {“languages”: [“English”, “French”, 42]}
The correct answer is “Yes”, but the quiz marks that answer as incorrect. I believe this has more to do with swift because this is valid JSON. JSON arrays can contain various data types. Maybe the question needs to be reworded to ask if this is valid JSON for swift?
The quiz is correct and the reason is that the expectation for JSON arrays is that they are the same data type. Languages are described in words, not numbers, therefore the expected data type is String.
If you paste that JSON
{"languages": ["English", "French", 42]}
into app.quicktype.io you get the following struct to deal with the fact that there are data mismatches in the array. It throws an error when it detects a mismatching data type.
struct Welcome: Codable {
let languages: [Language]
}
enum Language: Codable {
case integer(Int)
case string(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(Int.self) {
self = .integer(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(Language.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Language"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .integer(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}
It is not that the JSON is invalid, it is Swift arrays cannot contain multiple types. This is 100% valid JSON and other languages, such as JS/TS, Rust, and more can handle multiple types with no problem.
This is extremely important to understand in app development because companies can launch on multiple platforms. These same companies may have split development teams (backend, frontend, mobile, etc.) all making different decisions and all having different requirements.
This particular JSON is easily handled in other platforms, just not Swift. For example, in typescript I would do this:
type Languages: Array<string | number>
In all the years that I have been writing Swift code, I have yet to see any JSON file that has multiple data types for a given property. The fact that Swift is known as a type safe language means that there are rules that have to be abided by.
Right, but the question asks if that is valid JSON which it is. Additionally, couldn’t I just create my model in swift with Any type to handle a JSON array with multiple types?
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/types/#Any-Type