首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI构造与解码JSON

SwiftUI构造与解码JSON
EN

Stack Overflow用户
提问于 2022-06-21 18:43:39
回答 1查看 58关注 0票数 1

使用URLSession从我的自定义API中获取水晶数据。试着按标题列出。

我知道这里有些地方不对,但不确定是什么。查找了所有的JSON字典解码,但没有运气。

Response结构是多余的还是我可以简单地用JSONDecoder()解码[String:Crystal]?如有任何指导和建议,我们将不胜感激。我知道如何使用数组来完成这个任务,但是字典让我很不爽。

GET https://lit-castle-74820.herokuapp.com/api/crystals

代码语言:javascript
复制
{
  "amethyst": {
    "composition": "silicon dioxide",
    "formation": "forms when gas bubbles occur in lava and become trapped",
    "colour": "purple",
    "metaphysical": [
      "calming",
      "healing",
      "especially for headaches",
      "fatigue, & anxiety"
    ]
  },
  "clear quartz": {
    "composition": "silicon dioxide",
    "formation": "forms when gas bubbles occur in lava and become trapped",
    "colour": "colourless or appears white",
    "metaphysical": "master healer for all ailments; amplifies the healing vibration of other stones placed nearby"
  },
  "moss agate": {
    "composition": "silicon dioxide, commonly featuring manganese or iron",
    "formation": "formed from weathered volcanic rock",
    "colour": "colourless with specks of white, green, blue, or brown",
    "metaphysical": [
      "gentle healing",
      "promotes tranquility",
      "cures physical ailments (inflammation, cold & flu)"
    ]
  },
  "carnelian": {
    "composition": "silicon dioxide with iron impurity",
    "formation": "formed from a combination of the silica minerals quartz and moganite",
    "colour": "orange or red often featuring yellow",
    "metaphysical": [
      "promotes life-force",
      "vitality",
      "energizes body and mind"
    ]
  },
  "spirit quartz": {
    "composition": "silicon dioxide",
    "formation": "forms when gas bubbles occur in lava and become trapped",
    "colour": "purple, yellowish brown, light grey",
    "metaphysical": [
      "assists in spiritual journey",
      "uplifts and promotes vibration"
    ]
  },
  "amazonite": {
    "composition": "potassium feldspar",
    "formation": "formed in deep sea igneous rocks that cool very slowly",
    "colour": "blue or green with white speckles or lines",
    "metaphysical": [
      "Soothes anxiety and overthinking",
      "helps heal emotional trauma"
    ]
  },
  "tourmaline": {
    "composition": "silicate of boron and aluminum",
    "formation": "Pegmatite pockets underground that slowly cool and form crystals",
    "colour": "black or pink",
    "metaphysical": [
      "repels negative energy",
      "highly protective"
    ]
  },
  "pyrite": {
    "composition": "iron sulfide",
    "formation": "forms in sedimentary rocks in low oxygen environments",
    "colour": "gold",
    "metaphysical": [
      "abundance",
      "good luck",
      "emotional strength"
    ]
  }
}
代码语言:javascript
复制
struct Response: Codable {
    let crystals: [String:Crystal]
}

struct Crystal: Codable, Identifiable {
    var id = UUID()
    let composition, formation, color: String
    let metaphysical: [String]
}

struct ContentView: View {
    @State private var crystals: [String:Crystal] = [:]
    
    var body: some View {
        List(crystals) { crystal in
            (crystal.key)
        }.onAppear(perform: loadData)
    }
    
    func loadData() {
        guard let url = URL(string: "https://lit-castle-74820.herokuapp.com/api/crystals") else { return }
        URLSession.shared.dataTask(with: url) { data, _, error in
            guard let data = data else { return }
            do {
                let decodedResponse = try JSONDecoder().decode(Response.self, from: data)
                DispatchQueue.main.async {
                  self.crystals = decodedResponse.crystals
               }
            } catch let jsonError as NSError {
              print("JSON decode failed: \(jsonError)")
            }
        }.resume()
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-21 20:10:33

这是一个有点奇怪的API。您所面临的问题是在Crystal结构中。metaphysical似乎是一个String数组,但至少在一个例子中,它是一个简单的String

编辑:

因为这是一个自定义API,所以您应该编辑它并返回一个String数组,即使集合中只有一个元素。

此外:

  • 您的解码方法无法工作,因为JSON中没有顶级元素。这是一个[String:Crystal].
  • You,在结构color -> colour

中有一个错误

然后你可以使用:

代码语言:javascript
复制
try JSONDecoder().decode([String:Crystal].self, from: data)

原件:

如果此数据是静态的(不改变),则可以使用以下解决方案:

代码语言:javascript
复制
struct Response: Codable {
    let amethyst, mossAgate, carnelian, spiritQuartz, amazonite, tourmaline, pyrite: GemWithArray
    let clearQuartz: GemWithoutArray

    enum CodingKeys: String, CodingKey {
        case amethyst
        case clearQuartz = "clear quartz"
        case mossAgate = "moss agate"
        case carnelian
        case spiritQuartz = "spirit quartz"
        case amazonite, tourmaline, pyrite
    }
}

struct GemWithArray: Codable {
    let composition, formation, colour: String
    let metaphysical: [String]
}

struct GemWithoutArray: Codable {
    let composition, formation, colour, metaphysical: String
}

把它解码成:

代码语言:javascript
复制
try JSONDecoder().decode(Response.self, from: data)

但是有一种方法可以使它更加健壮,并且能够将它作为[String:GemWithArray]来处理。您需要在GemWithArray结构中使用自定义初始化程序。在它中,尝试将metaphysical解码到一个[String],如果它失败了,创建一个数组,将其解码并附加为String

代码语言:javascript
复制
struct GemWithArray: Codable {
    let composition, formation, colour: String
    let metaphysical: [String]
    
    enum CodingKeys: String, CodingKey{
        case composition, formation, colour, metaphysical
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        composition = try container.decode(String.self, forKey: .composition)
        formation = try container.decode(String.self, forKey: .formation)
        colour = try container.decode(String.self, forKey: .colour)
        
        if let metaphysical = try? container.decode([String].self, forKey: .metaphysical){
            self.metaphysical = metaphysical
        } else{
            metaphysical = [try container.decode(String.self, forKey: .metaphysical)]
        }
    }
}

把它解码成:

代码语言:javascript
复制
try JSONDecoder().decode([String:GemWithArray].self, from: data)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72705733

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档