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
相关产品推荐
相关产品推荐

