将 JSON 解析为正确的结构格式

问题描述 投票:0回答:1

作为 swiftUI 开发的新手,目前不太了解,如果这个问题已经得到解答,我很抱歉,但我找不到(或至少理解)任何东西来解决我的问题。为了练习,我正在尝试创建第一个应用程序,一个标志测验。虽然可能很容易做到,但我很难回答这两个问题:

  1. 存储旗帜图像的最佳解决方案是什么?如果我需要为应用程序创建更多功能,它会在资产文件夹中,尝试从 API 检索它们或将它们存储在免费的后端服务中作为 Firebase 吗?

  2. 我在我这边寻求 API 解决方案,但我正在努力正确地完成它。我想要一个“Flag”结构数组,允许我随机选择一个“Flag”以其关联的“shortName”(从 URL 检索正确的标志)和“Name”显示在视图中。这是我到目前为止所拥有的:


import Foundation

let decoder = JSONDecoder()

struct Flag: Codable, Identifiable {
    var flagLink: String
    var flagDetails: FlagDetails
    var id = UUID()
    
    init(flagLink: String, flagDetails: FlagDetails) {
        self.flagDetails = flagDetails
        self.flagLink = "https://flagcdn.com/w320/\(flagDetails.shortName).png"
    }
}

struct FlagDetails: Codable {
    var shortName: String
    var name: String
}


func getJSON(){
    
    guard let urlJSON = URL(string: "https://flagcdn.com/fr/codes.json") else {
        print("Invalid URL")
        return
    }
    URLSession.shared.dataTask(with: urlJSON) { (data, response, error) -> Void in
        if error == nil && data != nil {
            do {
                let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: Any]
                print()
    
            } catch {
                print("Invalid data: \(error)")
            }
        }
    }.resume()
}

网站提供的JSON文件格式如下:

{
    "ad": "Andorra",
    "af": "Afghanistan",
    "ag": "Antigua-et-Barbuda",
    "ai": "Anguilla"
}

创建字典后,我想将 CodingKey 分配给“shortName”,将 CodingKey 的值分配给“name”,以便在我从视图中请求随机问题时正确初始化链接。 我很确定这绝对不是最好的方法,但作为一个真正的初学者,稍微使用 JSON 文件可以帮助我很多。

非常感谢您提供的任何帮助!

json swift decoding
1个回答
0
投票
  1. 我会使用框架来下载图像,例如 Kingfisher 或 ImageLoaderSwift。

  2. 关于回答你的第二个问题:

您可以使用

for KEY in DICTIONARY
遍历字典,然后将值添加到数组 (
countryFlags
)。

如果你可以直接将 json 字符串转换为结构,你只需要 Codable,在这种情况下你不能,因为你需要一个数组而不是字典。

请注意,我不是在 Mac 上,所以我无法测试代码。

struct Flag {
  /.../

  // Simplified constructor for you
  init(shortName: String, name: String) {
      self.flagDetails = FlagDetail(shortName: shortName, name: name)
      self.flagLink = "https://flagcdn.com/w320/\(shortName).png"
  }
}

struct FlagDetails {
    /.../
}

var countryFlags = [Flag]()

func getJSON(){
    
    guard let urlJSON = URL(string: "https://flagcdn.com/fr/codes.json") else {
        print("Invalid URL")
        return
    }

    URLSession.shared.dataTask(with: urlJSON) { (data, response, error) -> Void in
        if error == nil && data != nil {
            do {
                // Changed [String: Any] to [String: String]
                let countryDictionary = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: String]

                // NEW CODE
                for (shortName, name) in countryDictionary {
                  countryFlags.append( Flag(shortName: shortName, name: name) )
                }

                print(countryFlags)

            } catch {
                print("Invalid data: \(error)")
            }
        }
    }.resume()
}
© www.soinside.com 2019 - 2024. All rights reserved.