简体   繁体   中英

Cannot convert value of type '(key: String, value: AnyObject)' to expected argument type '[String : AnyObject]'

I'm trying to get to the url of thumbnail_images from the JSON response I got as shown in this picture below: 在此输入图像描述 So in order to reach to the url I made a class called Posts in which

class Posts: NSObject {

    var title: String?
    var excerpt: String?
    var content: String?
    var thumbnail_images: [ThumbImages] = []

    init(dict: [String: AnyObject])
    {
        super.init()

        self.title = dict["title"] as? String
        self.excerpt = dict["excerpt"] as? String
        self.content = dict["content"] as? String

        if let postImage = dict["thumbnail_images"] as? [String: AnyObject] {

            for img in postImage  {
                self.thumbnail_images.append(ThumbImages(dict: img))
            }
        }
    }
}

On the line self.thumbnail_images.append(ThumbImages(dict: img)) I get this error:

Cannot convert value of type '(key: String, value: AnyObject)' to expected argument type '[String : AnyObject]'

That is it for my questions but I think it's relevant to share more code as in order to reach to url I had to make to more classes ThumbImages and MedLargeImage . Which has the following code:

class ThumbImages: NSObject {

    var medium_large: [MedLargeImage] = []

    init(dict: [String: AnyObject]) {

        super.init()

        if let imgURL = dict["medium_large"] {

            for iURL in imgURL as! [AnyObject] {
                medium_large.append(MedLargeImage(dict: iURL as! [String : AnyObject]))
            }
        }
    }

As you can see in the screenshot. So finally I'm in the room where I can get the URL:

class MedLargeImage: NSObject {

    var imageUrl: String?

    init(dict: [String: AnyObject]) {

        super.init()
        self.imageUrl = dict["url"] as? String

    }
}

UPDATE:

If I change if let postImage in Posts class to:

if let postImage = dict["thumbnail_images"] as? [[String: AnyObject]] {

            for img in postImage  {
                self.thumbnail_images.append(ThumbImages(dict: img))
            }
        }

The error is gone but for the if condition never gets true.

  • First of all classes are supposed to be named in singular form Post / ThumbImage . The datasource array eg posts contains Post instances and each Post instance contains an array thumbnailImages of ThumbImage instances. These semantics make it easier to understand the design.
  • Second of all JSON dictionaries in Swift 3+ are [String:Any]
  • Third of all according to the initialization rules the super call must be performed after initializing all stored properties.

The value of key thumbnail_images is a dictionary containing dictionaries. The error occurs because you are using the array enumeration syntax which treats the dictionary as an array of tuples.

The dictionary can be parsed to use the key as size name and the value to pass the parameters.

I have no idea why you are using NSObject subclasses but I'm sure you have your reasons.


This is the Thumbnail class

class ThumbImage: NSObject {

    let size: String
    var url : URL?
    let width : Int
    let height : Int

    init(size : String, parameters: [String: Any]) {

        self.size = size
        if let urlString = parameters["url"] as? String {
            self.url = URL(string: urlString)
        }
        self.width = parameters["width"] as? Int ?? 0
        self.height = parameters["height"] as? Int ?? 0
        super.init()
    }
}

and this the Post class

class Post: NSObject {

    var title: String
    var excerpt: String
    var content: String
    var thumbnailImages = [ThumbImage]()

    init(dict: [String: Any])
    {
        self.title = dict["title"] as? String ?? ""
        self.excerpt = dict["excerpt"] as? String ?? ""
        self.content = dict["content"] as? String ?? ""
        super.init()
        if let images = dict["thumbnail_images"] as? [String: [String:Any] ]  {
            for (key, value) in images {
                thumbnailImages.append(ThumbImage(size: key, parameters: value))
            }
        }
    }
}

You are seeing that error message because you are looping over postImage as if it's an array, when it's actually a dictionary. In your ThumbImages class initialiser, you are expecting to take in a dictionary. However, since you are looping through the postImage dictionary, this returns you tuples in key value pairs instead.

Hence when you try to pass in this tuple into the ThumbImages initialiser, the compiler complains that it is unable to convert your tuple into a dictionary.

Passing in the dictionary immediately will resolve the error:

if let postImage = dict["thumbnail_images"] as? [String: AnyObject] {
    self.thumbnail_images.append(ThumbImages(dict: postImage))
}

You cannot pass tuple as dictionary directly. instead use this: let dicFromArray = [tuple.key :tuple.value]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM