You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Swift Codable解析维基百科API返回的JSON数据

用Swift Codable解析维基百科API的JSON数据

没问题,我来帮你搞定这个解析需求~首先咱们得先把返回的JSON结构拆解清楚,这样才能精准对应到Swift的Codable模型里:

{
"batchcomplete": "",
"query": {
"pageids": [ "143540" ],
"pages": {
"143540": {
"pageid": 143540,
"ns": 0,
"title": "Poinsettia",
"extract": "The poinsettia... "
}
}
}
}

可以看到整个数据分为三层结构:

  • 最外层根对象,包含batchcomplete和query字段
  • query对象里有pageids数组,以及键为页面ID字符串的pages字典
  • 每个pages字典的值是具体的页面信息对象,包含pageid、ns、title、extract这些核心字段

第一步:定义对应的Codable模型

根据上面的结构,咱们可以直接写出匹配的Codable结构体:

// 根响应模型
struct WikipediaResponse: Codable {
    let batchcomplete: String?
    let query: WikipediaQuery
}

// Query部分的模型
struct WikipediaQuery: Codable {
    let pageids: [String]
    let pages: [String: WikipediaPage]
}

// 页面详情模型
struct WikipediaPage: Codable {
    let pageid: Int
    let ns: Int
    let title: String
    let extract: String
}

这里要注意pages字段用[String: WikipediaPage]类型,正好匹配返回的动态页面ID键的字典结构,Codable会自动处理这种字典的解码逻辑。

第二步:实现网络请求与解析逻辑

接下来写一个实际的异步请求函数,包含网络请求、状态码校验和JSON解码:

func fetchPoinsettiaPage() async throws -> WikipediaPage? {
    // 替换成你的维基百科API请求URL
    guard let url = URL(string: "你的维基百科API请求URL") else {
        throw NSError(domain: "InvalidURL", code: 0, userInfo: [NSLocalizedDescriptionKey: "无效的请求URL"])
    }
    
    // 发起网络请求
    let (data, response) = try await URLSession.shared.data(from: url)
    
    // 校验HTTP响应状态
    guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
        throw NSError(domain: "NetworkError", code: 0, userInfo: [NSLocalizedDescriptionKey: "网络请求失败"])
    }
    
    // 解码JSON数据
    let decoder = JSONDecoder()
    let wikiResponse = try decoder.decode(WikipediaResponse.self, from: data)
    
    // 从pages字典中取出第一个页面数据(如果存在的话)
    return wikiResponse.query.pages.values.first
}

第三步:调用示例

你可以在异步上下文里调用这个函数,比如SwiftUI的Task或者UIKit的异步方法中:

// 示例调用
Task {
    do {
        if let page = try await fetchPoinsettiaPage() {
            print("页面标题:\(page.title)")
            print("页面摘要:\(page.extract)")
        } else {
            print("未找到对应的页面数据")
        }
    } catch {
        print("请求或解析错误:\(error.localizedDescription)")
    }
}

如果遇到字段可能缺失的情况,你可以给模型里的字段加上?变成可选类型,比如let extract: String?,这样即使字段为空或者不存在,解码也不会崩溃。

内容的提问来源于stack exchange,提问作者djeetee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:54:48