SWIFT尝试使用嵌套数组获取字典中的值

e0bqpujr  于 2022-09-19  发布在  Swift
关注(0)|答案(1)|浏览(199)

嘿,大家好,我有这个https://www.googleapis.com/customsearch/v1?key=********&cx=017576662512468239146:omuauf_lfve&q=water接口

{
  "kind": "customsearch#search",
  "url": {
    "type": "application/json",
    "template": "https://www.googleapis.com/customsearch/v1?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&safe={safe?}&cx={cx?}&sort={sort?}&filter={filter?}&gl={gl?}&cr={cr?}&googlehost={googleHost?}&c2coff={disableCnTwTranslation?}&hq={hq?}&hl={hl?}&siteSearch={siteSearch?}&siteSearchFilter={siteSearchFilter?}&exactTerms={exactTerms?}&excludeTerms={excludeTerms?}&linkSite={linkSite?}&orTerms={orTerms?}&relatedSite={relatedSite?}&dateRestrict={dateRestrict?}&lowRange={lowRange?}&highRange={highRange?}&searchType={searchType}&fileType={fileType?}&rights={rights?}&imgSize={imgSize?}&imgType={imgType?}&imgColorType={imgColorType?}&imgDominantColor={imgDominantColor?}&alt=json"
  },
  "queries": {
    "request": [
      {
        "title": "Google Custom Search - water",
        "totalResults": "11580000000",
        "searchTerms": "water",
        "count": 1,
        "startIndex": 1,
        "inputEncoding": "utf8",
        "outputEncoding": "utf8",
        "safe": "off",
        "cx": "017576662512468239146:omuauf_lfve"
      }
    ],
    "nextPage": [
      {
        "title": "Google Custom Search - water",
        "totalResults": "11580000000",
        "searchTerms": "water",
        "count": 1,
        "startIndex": 2,
        "inputEncoding": "utf8",
        "outputEncoding": "utf8",
        "safe": "off",
        "cx": "017576662512468239146:omuauf_lfve"
      }
    ]
  },
  "context": {
    "title": "CS Curriculum",
    "facets": [
      [
        {
          "anchor": "Lectures",
          "label": "lectures",
          "label_with_op": "more:lectures"
        }
      ],
      [
        {
          "anchor": "Assignments",
          "label": "assignments",
          "label_with_op": "more:assignments"
        }
      ],
      [
        {
          "anchor": "Reference",
          "label": "reference",
          "label_with_op": "more:reference"
        }
      ]
    ]
  },
  "searchInformation": {
    "searchTime": 0.380675,
    "formattedSearchTime": "0.38",
    "totalResults": "11580000000",
    "formattedTotalResults": "11,580,000,000"
  },
  "items": [
    {
      "kind": "customsearch#result",
      "title": "Projects: Material Based Splashing of Water Drops - CAVE",
      "htmlTitle": "Projects: Material Based Splashing of Water Drops - CAVE",
      "link": "https://www1.cs.columbia.edu/CAVE/projects/mat_splash/matsplash.php",
      "displayLink": "www1.cs.columbia.edu",
      "snippet": "In general, the distribution of droplets of a splash depends on the drop size and velocity; the surface roughness, rigidity, and wetness; and the angle of ...",
      "htmlSnippet": "In general, the distribution of droplets of a splash depends on the drop size and velocity; the surface roughness, rigidity, and wetness; and the angle of ...",
      "cacheId": "MmD3HwYnsbMJ",
      "formattedUrl": "https://www1.cs.columbia.edu/CAVE/projects/mat_splash/matsplash.php",
      "htmlFormattedUrl": "https://www1.cs.columbia.edu/CAVE/projects/mat_splash/matsplash.php",
      "pagemap": {
        "cse_thumbnail": [
          {
            "src": "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQ1-s5F6RFCTzoWahOEFmCmscY8RmGuUGoPADYZ66rkQIDA8Y9oEZkNFuA",
            "width": "388",
            "height": "130"
          }
        ],
        "cse_image": [
          {
            "src": "https://www1.cs.columbia.edu/CAVE/projects/mat_splash/images/main_image.png"
          }
        ]
      },
      "labels": [
        {
          "name": "assignments",
          "displayName": "Assignments",
          "label_with_op": "more:assignments"
        }
      ]
    }
  ]
}

我保存响应,并尝试在本地处理该响应。我想从CSE_IMAGE中获取值,但是如果我用我的函数加载json文件,则页面Map的值为空,例如,索引0上的另一个键值可用。我的模型是通过QuickType生成的,所以它应该是正确的。下面是我的解析json函数:

static func parseJson() {
        guard let path = Bundle.main.path(forResource: "response", ofType: "json") else {
        return
    }

    let url = URL(fileURLWithPath: path)

    var result: TotalResults?

    do {
        let jsonData =  try Data(contentsOf: url)
        result = try JSONDecoder().decode(TotalResults.self, from: jsonData)

        if let result = result {
            print(result)
        } else {
            print("Failed to pase")
        }
    }
    catch {
        print("Error (error)")
    }
}
dldeef67

dldeef671#

试着这样做,稍微修改一下https://app.quicktype.io/生成的代码(对我来说很好):

注意,您仍然需要查看服务器文档,以确定哪些属性是可选的。

struct ContentView: View {
    @State var cseImageSet = [CSEImage]()
    var body: some View {
        List(cseImageSet) { cse in
            Text(cse.src)
        }
        .onAppear {
            parseJson()
        }
    }

    func parseJson() {
        guard let path = Bundle.main.path(forResource: "response", ofType: "json") else { return }
        let url = URL(fileURLWithPath: path)
        do {
            let jsonData =  try Data(contentsOf: url)
            let result = try JSONDecoder().decode(TotalResults.self, from: jsonData)
            result.items.forEach{ item in
                self.cseImageSet = item.pagemap.cseImage
            }
        }
        catch {
            print("Error (error)")
        }
    }
}

// MARK: - TotalResults
struct TotalResults: Codable {
    let kind: String
    let url: URLClass
    let queries: Queries
    let context: Context
    let searchInformation: SearchInformation
    let items: [Item]
}

// MARK: - Context
struct Context: Codable {
    let title: String
    let facets: [[Facet]]
}

// MARK: - Facet
struct Facet: Codable {
    let anchor, label, labelWithOp: String

    enum CodingKeys: String, CodingKey {
        case anchor, label
        case labelWithOp = "label_with_op"
    }
}

// MARK: - Item
struct Item: Identifiable, Codable {
    let id = UUID()
    let kind, title, htmlTitle: String
    let link: String
    let displayLink, snippet, htmlSnippet, cacheID: String
    let formattedURL, htmlFormattedURL: String
    let pagemap: Pagemap
    let labels: [Label]

    enum CodingKeys: String, CodingKey {
        case kind, title, htmlTitle, link, displayLink, snippet, htmlSnippet
        case cacheID = "cacheId"
        case formattedURL = "formattedUrl"
        case htmlFormattedURL = "htmlFormattedUrl"
        case pagemap, labels
    }
}

// MARK: - Label
struct Label: Identifiable, Codable {
    let id = UUID()
    let name, displayName, labelWithOp: String

    enum CodingKeys: String, CodingKey {
        case name, displayName
        case labelWithOp = "label_with_op"
    }
}

// MARK: - Pagemap
struct Pagemap: Codable {
    let cseThumbnail: [CSEThumbnail]
    let cseImage: [CSEImage]

    enum CodingKeys: String, CodingKey {
        case cseThumbnail = "cse_thumbnail"
        case cseImage = "cse_image"
    }
}

// MARK: - CSEImage
struct CSEImage: Identifiable, Codable {
    let id = UUID()
    let src: String
}

// MARK: - CSEThumbnail
struct CSEThumbnail: Identifiable, Codable {
    let id = UUID()
    let src: String
    let width, height: String
}

// MARK: - Queries
struct Queries: Identifiable, Codable {
    let id = UUID()
    let request, nextPage: [NextPage]
}

// MARK: - NextPage
struct NextPage: Identifiable, Codable {
    let id = UUID()
    let title, totalResults, searchTerms: String
    let count, startIndex: Int
    let inputEncoding, outputEncoding, safe, cx: String
}

// MARK: - SearchInformation
struct SearchInformation: Codable {
    let searchTime: Double
    let formattedSearchTime, totalResults, formattedTotalResults: String
}

// MARK: - URLClass
struct URLClass: Codable {
    let type, template: String
}

您还可以执行以下操作:

struct ContentView: View {
    @State var results: TotalResults?

    var body: some View {
        List (results?.items ?? []) { item in
            ForEach(item.pagemap.cseImage){ cse in
                Text(cse.src)
            }
        }
        .onAppear {
            results = parseJson()
        }
    }

    func parseJson() -> TotalResults? {
        guard let path = Bundle.main.path(forResource: "response", ofType: "json") else { return nil }
        let url = URL(fileURLWithPath: path)
        do {
            let jsonData =  try Data(contentsOf: url)
            return try JSONDecoder().decode(TotalResults.self, from: jsonData)
        }
        catch {
            print("Error (error)")
        }
        return nil
    }
}

相关问题