Swift和JSON问题

时间:2018-10-29 16:54:47

标签: arrays json swift

我是Swift的新手,目前正在玩Stickers。

我有一个具有以下结构的JSON文件:

{
 "stickers": [{
    "filename": "happy_face",
    "description": "Happy Face",
    "premium": "false",
    "categories": ["blue", "green", "red"],
    "genders": ["male", "female"]
 },{
    "filename": "sad_face",
    "description": "Sad Face",
    "premium": "false",
    "categories": ["blue", "green", "red", "yellow"],
    "genders": ["male"]
  }]
}

贴纸将具有相同的文件名,但会根据它们的类别和性别分成文件夹。

我可以很好地读取JSON数据。我的问题是,当我尝试利用JSON数据时。

我的目标是根据标签的类别将其分开,标签的种类可能会有所不同,用户稍后将可以切换类别,并显示正确的标签。

let stickerPack = StickerPack.load()
let allStickers = stickerPack!["stickers"] as? [[AnyHashable : Any]]

func getStickersWithCategory(category: String){

var stickers = [AnyObject]()

for sticker in allStickers! {
    let cat = sticker["categories"] as? [String]
    for item in cat! {
        if item.contains(category){
            stickers.append(sticker)
       }
    }
  }
}

结果是

  

“参数类型'[AnyHashable:Any]'不符合预期的类型'AnyObject'”

有人能指出我正确的方向吗?这个JSON结构可能吗?还是将每个类别和性别分别设置为不同的结构更好?这将导致很多重复。但是也许我通过尝试以这种方式保持JSON结构来制造更多问题。

感谢所有帮助!

2 个答案:

答案 0 :(得分:0)

问题在于您将allStickers声明为let allStickers = stickerPack!["stickers"] as? [[AnyHashable : Any]],这意味着其类型将为[[AnyHashable:Any]]?Array<Dictionary<AnyHashable:Any>>。当您遍历for sticker in allStickers!中的数组时,sticker的类型将为Dictionary<AnyHashable:Any>Dictionary是一个结构,因此不符合AnyObject,因此您不能向sticker添加stickersAnyObjects被声明为{{1}的数组}。

因此,将var stickers = [AnyObject]()更改为var stickers = [Any](),或更具体地说将var stickers = [[AnyHashable:Any]]()应该可以解决您的问题。

func getStickersWithCategory(category: String){
    var stickers = [[AnyHashable:Any]]()

    for sticker in allStickers! {
        let cat = sticker["categories"] as? [String]
        for item in cat! {
            if item.contains(category){
                stickers.append(sticker)
            }
        }
    }
}

在处理JSON时,建议您在Swift 4中使用Codable

答案 1 :(得分:0)

更具体的类型,可以避免这种错误。

此JSON数组为[[String:Any]]从不 AnyHashable,因为键必须是字符串

let allStickers = stickerPack!["stickers"] as? [[String:Any]]

stickers是相同的类型,从不是包含AnyObject的类型。所有JSON类型都是值类型(Any)。

var stickers = [[String:Any]]()

您可以过滤数组 swiftier ,建议安全地拆开所有可选项

if let stickerPack = StickerPack.load(),
   let allStickers = stickerPack["stickers"] as? [[String:Any]] {
     stickers = allStickers.filter({ (sticker) -> Bool in
         guard let categories = sticker["categories"] as? [String] else { return false }
         return categories.contains(category)
     })
...