For the purpose of my app I'm using JSON objects that are defined like:
typealias JSONObject = [String:JSONValue]
Where JSON Value is a protocol to which possible types are conforming to:
protocol JSONValue {}
extension String: JSONValue {}
extension Int: JSONValue {}
extension Double: JSONValue {}
extension Bool: JSONValue {}
extension NSNull: JSONValue {}
extension JSONObject: JSONValue {}
(I prefer using this way instead of creating a JSONValue enum with .string(value), .int(value) etc... My code is private and no-one will be adding other extensions)
To handle arrays, I've added:
extension [JSONValue]: JSONValue {}
So that any JSONValue can be a primitive, an array, or a dictionary (JSONObject)
Everything is working fine. I'm just having an issue with arrays. See this example :
var myObject = JSONObject()
myObject["primitive"] = "OK"
myObject["array"] = ["OK"]
let myObjectAsJSONValue: JSONValue = myObject // OK
var myArray = [JSONObject]()
myArray.append(myObject)
let myArrayAsJSONValue: JSONValue = myArray // Failing (Protocol 'JSONValue' requires the types 'JSONObject' (aka 'Dictionary<String, any JSONValue>') and 'any JSONValue' be equivalent)
I don't understand the error I'm getting since JSONObject conforms to JSONValue (so can be handled as "any JSONValue")
Any help??
Thanks!
Edit: Fixed my issue by replacing:
extension [JSONValue]: JSONValue {}
With:
extension Array : JSONValue where Element : JSONValue {}
I don't really understand the difference but it seems to work...
As stated in the edit, you should write the array extension like this:
extension Array : JSONValue where Element : JSONValue {}
This is different from extension [JSONValue] ...
in that extension [JSONValue]
declares an extension on only one type - Array<any JSONValue>
.
So if you just declare myArray
as:
var myArray = [any JSONValue]()
there will be no error.
The myArray
in your code has type Array<JSONObject>
. This is a different type from Array<any JSONValue>
, and therefore extension [JSONValue]
does not apply to it - it does not conform to JSONValue
.
If the extension is extension Array : JSONValue where Element : JSONValue
, then the extension applies to all Array
types, where the Element
type conforms to JSONValue
. Since JSONObject
conforms to JSONValue
, Array<JSONObject>
does too.