0

I have this protocol

protocol JsonConvertable {
    init?(_ underlyingValue: UnderlyingValue)
}

UnderlyingValue is an enum:

enum UnderlyingValue {
    case string(String)
    case int(Int)
    case double(Double)
    case bool(Bool)
    case array(Array<Dictionary<String, AnyObject>>)
    case dictionary(Dictionary<String, AnyObject>)

    init?(value: JsonConvertable) {
        switch rawValue {
        case let value as [String: AnyObject]: self = .dictionary(value)
        case let value as Array<[String: AnyObject]>: self = .array(value)
        case let value as Double: self = .double(value)
        case let value as Int: self = .int(value)
        case let value as Bool: self = .bool(value)
        case let value as String: self = .string(value)
        default: return nil
        }
    }
}

I can extend most types as follows

extension String: JsonConvertable {
    init?(_ underlyingValue: UnderlyingValue) {
        switch underlyingValue {
        case .bool(let value): self = value
        default: return nil
    }
}

However the Array extension is giving me the error Cannot assign value of type 'Array<Dictionary<String, AnyObject>>' to type 'Array<_>'

extension Array: JsonConvertable {
    init?(_ underlyingValue: UnderlyingValue) {
        switch underlyingValue {
        case .array(let value): self = value
        default: return nil
        }
    }
}

I have tried everything I can think of but nothing is working. I tried to have JsonConvertable conform to ArrayLiteralConvertable, I have tried using generics in the init but I am just starting to understand generics and don't really know how it would be beneficial in this case, the same with AssociatedType. I have tried to constrict Element. I have been trying to get this to work for 2 whole days and everything I do seems to not make any headway. What am I missing?

1 Answer 1

4

In your extension method, you are extending Array which is a type of Array<_> and your _underlyingValue is type of Array<[String:AnyObject]>.

Have you try this way:

extension Array where Element:Dictionary<String, AnyObject>, Element:JsonConvertable  {
  init?(_underlyingValue : UnderlyingValue){
      switch _underlyingValue {
        case  .array(let value):
          self = value
        default:
          return nil
      }
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

I will give this a chance once I can get back to my project. I have tried something similar, I remember getting an error message that you can only constrict Element with a protocol and not a concrete type.
The error below shows up at the extension signature type 'Element' constrained to non-protocol type 'Dictionary<String, AnyObject>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.