Search code examples
swiftnsobjectsubtypeanyobject

swift - '(AnyObject)' is not a subtype of 'NSObject'


I'm new to swift development, I followed a tutorial and everything was fine until I came across this error and I don't know how to fix it. Can you help me ?

if let json = response.result.value {
    let jsonArray:NSArray = json as! NSArray
    /// On fait la boucle pour avoir la liste globale des éléments a afficher
    for i in 0..<jsonArray.count {
        self.OPlays.append(Playlist(
            title:(jsonArray[i] as AnyObject).value(forKey: "title") as? String,
                artist:(jsonArray[i] as AnyObject).value(forKey: "artist") as? String,
                categorie:(jsonArray[i] as AnyObject).value(forKey: "categorie") as? String,
                cover_url:(jsonArray[i] as AnyObject).value(forKey: "cover_url") as? String)
        )
    }
    self.tableViewPlaylist.reloadData()
}        

News file correct.

if let json = response.result.value {
    let jsonArray:NSArray = json as! NSArray

    /// On fait la boucle pour avoir la liste globale des éléments a afficher
    for i in 0..<jsonArray.count {
        self.OPlays.append(Playlist(
            id: (jsonArray[i] as AnyObject).value(forKey: "id") as? Int,
            title: (jsonArray[i] as AnyObject).value(forKey: "title") as? String,
            artist: (jsonArray[i] as AnyObject).value(forKey: "artist") as? String,
            cover_url: (jsonArray[i] as AnyObject).value(forKey: "cover_url") as? String,
            categorie: (jsonArray[i] as AnyObject).value(forKey: "categorie") as? String
        ))
    }
    self.tableViewPlaylist.reloadData()
}

Solution

  • I’d excise all of that AnyObject code:

    if let array = response.result.value as? [[String: Any]] {
        for dictionary in array {
            self.OPlays.append(Playlist(
                id: dictionary["id"] as? Int,
                title: dictionary["title"] as? String,
                artist: dictionary["artist"] as? String,
                categorie: dictionary["categorie"] as? String,
                cover_url: dictionary["cover_url"] as? String
            ))
        }
        self.tableViewPlaylist.reloadData
    }
    

    Personally, I’d go a step further and get out of the business of decoding your JSON manually. Use JSONDecoder.

    struct Playlist: Codable {
        let id: Int?
        let title: String?
        let artist: String?
        let categorie: String?
        let cover_url: String?
    }
    

    Then, assuming you have data that is the unwrapped Data object:

    do {
        self.OPlays = JSONDecoder().decode([Playlist].self, from: data)
    } catch {
        print(error)
    }
    

    Or, if you’re using Alamofire, consider Alamofire 5 which has a JSONDecoder-based response method.