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

Swift解析Google Custom Search API的og字段技术求助

解析Google Custom Search API结果获取og:image和og:title的Swift实现

别担心,这个需求用Swift的Codable就能轻松搞定,我之前做过类似的功能,给你一步步拆解:

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

Google Custom Search返回的JSON核心层级是:response -> items -> pagemap -> metatags,我们把这些层级用Codable结构体映射出来,重点处理带特殊字符的og字段:

// 最外层响应模型
struct GoogleSearchResponse: Codable {
    let items: [SearchItem]?
}

// 单个搜索结果项
struct SearchItem: Codable {
    let pagemap: PageMap?
}

// Pagemap结构
struct PageMap: Codable {
    let metatags: [MetaTag]?
}

// 元标签模型,映射og字段
struct MetaTag: Codable {
    let ogImage: String?
    let ogTitle: String?
    
    // 处理JSON里带冒号的键名
    enum CodingKeys: String, CodingKey {
        case ogImage = "og:image"
        case ogTitle = "og:title"
    }
}

第二步:发起请求并解析数据

用URLSession请求API,拿到返回数据后用JSONDecoder解析成自定义模型,再提取需要的og字段:

func fetchGoogleSearchResults(apiKey: String, cx: String, query: String) {
    guard let encodedQuery = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
          let url = URL(string: "https://www.googleapis.com/customsearch/v1?key=\(apiKey)&cx=\(cx)&q=\(encodedQuery)") else {
        print("无效的请求URL")
        return
    }
    
    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data, error == nil else {
            print(error?.localizedDescription ?? "未知错误")
            return
        }
        
        do {
            // 解析成自定义模型
            let searchResponse = try JSONDecoder().decode(GoogleSearchResponse.self, from: data)
            
            // 遍历每个搜索项提取og字段
            searchResponse.items?.forEach { item in
                guard let metatags = item.pagemap?.metatags, let firstMeta = metatags.first else {
                    // 没有metatags的情况,可做默认值处理
                    print("当前项无元标签数据")
                    return
                }
                
                let displayTitle = firstMeta.ogTitle ?? "无标题"
                let displayImageUrl = firstMeta.ogImage ?? "无图片链接"
                
                // 切回主线程更新UI(比如刷新列表)
                DispatchQueue.main.async {
                    print("标题:\(displayTitle),图片链接:\(displayImageUrl)")
                    // 这里可以把数据存入数据源,触发UI刷新
                }
            }
        } catch {
            print("解析错误:\(error.localizedDescription)")
        }
    }
    task.resume()
}

第三步:处理边界情况

实际场景里,部分搜索结果可能没有pagemap、metatags为空,或者缺失og字段,所以一定要用if let/guard let做可选绑定,避免崩溃。如果需要更严谨,还可以给缺失字段设置默认提示,或者做错误上报。

备选方案:手动解析(不推荐)

如果暂时不想定义模型,也可以用JSONSerialization手动解析,但类型不安全,容易出错:

do {
    if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
       let items = json["items"] as? [[String: Any]] {
        for item in items {
            if let pagemap = item["pagemap"] as? [String: Any],
               let metatags = pagemap["metatags"] as? [[String: Any]],
               let firstMeta = metatags.first {
                let title = firstMeta["og:title"] as? String ?? "无标题"
                let imageUrl = firstMeta["og:image"] as? String ?? "无图片链接"
                print(title, imageUrl)
            }
        }
    }
} catch {
    print(error)
}

总之,用Codable是最推荐的方式,类型安全且易维护,后续要扩展其他字段也非常方便,完全能满足你在App内展示数据的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 19:39:09