【问题标题】:Swift 3: Trying to parse JSON but keep getting type issuesSwift 3:尝试解析 JSON 但不断遇到类型问题
【发布时间】:2017-09-27 18:22:57
【问题描述】:

我正在从 Obj-c 转换为 Swift,有时它会非常令人沮丧,因为我在 Obj-C 中可以在几分钟内完成的简单任务会占用几个小时。我知道这是学习过程的一部分,但都是一样的。

我构建了一个测试应用程序,用歌曲名称查询 iTunes 并返回所有结果。但是对于我的生活,我似乎无法解析返回到个人字典级别。

我可以使用这段代码来挖掘到我认为我有一个字典数组的级别:

 if let dictData = dictJSON["Data"] as? [String:Any],  let arrResults = dictData["results"] as? Array<Any> {

然后我可以像这样遍历该数组:

for i in 1...arrResults.count {

for dictThisSong in arrResults { 

在任何一种情况下,我都会得到如下结果:

{
    artistId = 158038;
    artistName = "Fleetwood Mac";
    artistViewUrl = "https://itunes.apple.com/us/artist/fleetwood-mac/id158038?uo=4";
    artworkUrl100 = "http://is2.mzstatic.com/image/thumb/Music/v4/8e/75/28/8e752885-66d0-737c-11ef-4c706672997e/source/100x100bb.jpg";
    artworkUrl30 = "http://is2.mzstatic.com/image/thumb/Music/v4/8e/75/28/8e752885-66d0-737c-11ef-4c706672997e/source/30x30bb.jpg";
    artworkUrl60 = "http://is2.mzstatic.com/image/thumb/Music/v4/8e/75/28/8e752885-66d0-737c-11ef-4c706672997e/source/60x60bb.jpg";
    collectionCensoredName = Rumours;
    collectionExplicitness = notExplicit;
    collectionId = 594061854;
    collectionName = Rumours;
    collectionPrice = "10.99";
    collectionViewUrl = "https://itunes.apple.com/us/album/the-chain/id594061854?i=594061861&uo=4";
    country = USA;
    currency = USD;
    discCount = 1;
    discNumber = 1;
    isStreamable = 0;
    kind = song;
    previewUrl = "https://audio-ssl.itunes.apple.com/apple-assets-us-std-000001/Music/v4/04/1d/85/041d85eb-f1fe-2d47-1ec7-2540582cece7/mzaf_3322367551095292692.plus.aac.p.m4a?accessKey=1516884136_9174591730773045036_io%2Bc9w6hmWHjPZOpZEgG1nZm9Hm%2FInFnTM%2FT3k8%2BoQZZW2ymomMWeZ8jGkN4TfX85U5U4WRYpxPN8e2svlMmBLE8boGG4aya9izAo%2FIvIMOZ4qt6XPuQQc5JstA%2FmihUGdKsa1Nbov9joyxnTnm7UlpKY2ZsqomfNv4SsJGfDG3cCgxtBoAOKR7Pj42lDYQN1jnRVqusi4Cpf9fHOXb5uA%3D%3D";
    primaryGenreName = Rock;
    releaseDate = "1977-02-04T08:00:00Z";
    trackCensoredName = "The Chain";
    trackCount = 11;
    trackExplicitness = notExplicit;
    trackId = 594061861;
    trackName = "The Chain";
    trackNumber = 7;
    trackPrice = "1.29";
    trackTimeMillis = 270213;
    trackViewUrl = "https://itunes.apple.com/us/album/the-chain/id594061854?i=594061861&uo=4";
    wrapperType = track;
}

如果我进行某种检查,我会得到 NSDictionary:

print(type(of: dictThisSong))

__NSDictionaryI
__NSDictionaryI
__NSDictionaryI
__NSDictionaryI
__NSDictionaryI
__NSDictionaryI
__NSDictionaryI...

但是,如果我尝试打印 dictThisSong["artistName"],则会收到 Type "Any" has no subscript members 错误。

所以,我想也许我必须转换为 NSDictionary,但这会引发错误:

无法将 Array 类型的值转换为 NSDictionary,如果我尝试转换为 Dictionary,则相同

所以在我看来,错误消息是说我正在尝试将数组转换为字典,但打印输出的类型表明我已经在使用字典。任何帮助,将不胜感激。

完整代码:

func parseJSONResults(dictJSON:Dictionary<String, Any>) {

        if let dictData = dictJSON["Data"] as? [String:Any],  let arrResults = dictData["results"] as? Array<Any> {
            for dictThisSong in arrResults {
                print(dictThisSong)
            }
        } else {
            print(dictJSON)
        }


    }

【问题讨论】:

  • arrResults 肯定比[Any] 更具体。您正在与强类型系统作斗争。 [Any]一个 I-have-no-idea-what-it-is 数组,但你知道这是一个字典数组,所以将其转换为 [[String:Any]]
  • Cast where, at this line: for dictThisSong in arrResults as? [[字符串:任意]]
  • 我写了一个答案。

标签: arrays json swift dictionary


【解决方案1】:

您正在与强类型系统作斗争。帮助编译器比编译器更能帮助你。

[Any] 是一个 I-have-no-idea-what-it-is 的数组,但你确实知道这是一个字典数组,所以将其转换为[[String:Any]]

   if let dictData = dictJSON["Data"] as? [String:Any],  
      let arrResults = dictData["results"] as? [[String:Any]] { ...

【讨论】:

  • 我宁愿把编译器从木棚后面拿出来,给它一个打击。 :D 唯一的区别是我必须强制将其转换为!不像?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-23
  • 1970-01-01
  • 2018-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多