1
votes

Using Swift and Alamofire, I'm trying to convert a single json response in an Object ((dictionary: [String: AnyObject])) with the append method,but when I'm trying it the compiler fails throwing this error :

cannot invoke initializer for type 'Object' with an argument list of type (dictionary:(String:AnyObject))

Any ideas to how can I solve it?

Important, the return of the getById function must be [Object]?

the json response

Optional(["name": object1, "_id": 5470def9e0c0be27780120d8, 
          "imageUrl": https://s3-eu-west-1.amazonaws.com/api-static/objects/5470def9e0c0b_180.png,
          "location": {
                        city = Madrid;
                        country = Spain;
                        }, 
          "desc": blablablabla.
])
class Object {

    var id: String!
    var name: String!
    var imageUrl: String!
    var location: [String: String]!

    init(dictionary: [String: AnyObject]) {
        id         = dictionary["_id"] as? String
        name       = dictionary["name"] as? String
        imageUrl   = dictionary["imageUrl"] as? String
        location   = dictionary["location"] as? [String: String]
    }
}
func getById(completionHandler: ([Object]?, NSError?) -> ()) {
                    Alamofire.request(Router.GetById("5470def9e0c0be27780121d7")).responseJSON { (request, response, json, error) in

            var object = [Object]()

            var jsonObj = json as? [String: AnyObject]

            for dictionary in jsonObj!{
                object.append(Object(dictionary:dictionary))

            }
                completionHandler(object, nil)
            } else {
                completionHandler(nil, error)
            }

 }
}
1

1 Answers

2
votes

As jsonObj is of type [String: AnyObject], when you're trying to iterate over it, dictionary is of type (String, AnyObject), representing a key and the value of the dictionary. That is why Swift can't instantiate your Object, as it requires a Dictionary and not a Tuple.

You should instantiate your jsonObj as [[String: AnyObject]].

Some extra remarks:

  1. Name your variables appropriately, object sounds like a single Object, but actually is an array of Objects. Change this to something like objects: [Object]

  2. You are optionally downcasting in var jsonObj = json as? [String: AnyObject], but then afterwards you force unwrap this variable. Either force cast it using as! or use an if let statement to catch any nil values.

  3. Instead of looping over the values of the array, use map to wrap the initialiser.

So your code becomes:

func getById(completionHandler: ([Object]?, NSError?) -> ()) {
    Alamofire.request(Router.GetById("5470def9e0c0be27780121d7")).responseJSON { (request, response, json, error) in

        if let objects = json as? [[String: AnyObject]] {
            completionHandler(object.map {Object(dictionary: $0)}, nil)
            return
        }
        completionHandler(nil, error)
}

(or something like that, I don't know what that else was doing there)