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

Swift 4 Decodable解析含换行符的iTunes搜索API JSON失败求助

解决iTunes API JSON含换行符导致Swift Decodable解析失败的问题

我之前也踩过这个坑!iTunes API返回的description字段偶尔会夹带未转义的换行/回车符,直接导致Swift的Decodable解析崩溃——毕竟这种格式不符合JSON的严格规范。下面给你几个实测有效的解决办法:

方法一:预处理原始数据,修复JSON格式

在把请求返回的原始Data传给JSONDecoder之前,先手动清理掉非法的换行符,把它们转成合法的JSON转义序列。写个工具函数就行:

func cleanITunesJSONData(_ data: Data) -> Data? {
    guard let jsonString = String(data: data, encoding: .utf8) else {
        print("无法将数据转换为UTF-8字符串")
        return nil
    }
    // 替换所有换行/回车符为JSON合法的转义序列
    let cleanedString = jsonString
        .replacingOccurrences(of: "\r\n", with: "\\n")
        .replacingOccurrences(of: "\n", with: "\\n")
        .replacingOccurrences(of: "\r", with: "\\n")
    return cleanedString.data(using: .utf8)
}

使用的时候,先清理数据再解析:

// 假设你已经获取到API返回的rawData
guard let cleanedData = cleanITunesJSONData(rawData) else {
    return
}

do {
    let response = try JSONDecoder().decode(ITunesSearchResponse.self, from: cleanedData)
    // 处理解析后的结果
} catch {
    print("解析失败:\(error.localizedDescription)")
}

方法二:用第三方库兼容松散JSON

如果你不想自己写预处理逻辑,可以试试SwiftyJSON,它对不严格的JSON兼容性更好,能直接解析带未转义换行的内容,之后再映射到你的Codable结构体:

import SwiftyJSON

// 解析代码示例
if let json = try? JSON(data: rawData) {
    let description = json["results"][0]["description"].string
    let software = iTunesSoftware(iTunesDescription: description)
    // 处理数据
}

完整示例代码

为了让你更清楚,这里贴一个完整的请求+解析流程,包括定义完整的响应结构体:

import Foundation

// 定义iTunes搜索响应的顶层结构体
public struct ITunesSearchResponse: Codable {
    let results: [iTunesSoftware]
}

public struct iTunesSoftware: Codable {
    enum CodingKeys: String, CodingKey {
        case iTunesDescription = "description"
    }
    public var iTunesDescription: String?
}

// 清理JSON数据的工具函数
func cleanITunesJSONData(_ data: Data) -> Data? {
    guard let jsonString = String(data: data, encoding: .utf8) else {
        print("数据转字符串失败")
        return nil
    }
    let cleanedString = jsonString
        .replacingOccurrences(of: "\r\n", with: "\\n")
        .replacingOccurrences(of: "\n", with: "\\n")
        .replacingOccurrences(of: "\r", with: "\\n")
    return cleanedString.data(using: .utf8)
}

// 发起请求并解析
func fetchRuismakerSoftware() {
    guard let url = URL(string: "https://itunes.apple.com/search?term=Ruismaker&entity=software&media=software&limit=1") else {
        print("无效URL")
        return
    }
    
    let task = URLSession.shared.dataTask(with: url) { rawData, _, error in
        guard let rawData = rawData, error == nil else {
            print("请求错误:\(error?.localizedDescription ?? "未知错误")")
            return
        }
        
        guard let cleanedData = cleanITunesJSONData(rawData) else {
            print("数据清理失败")
            return
        }
        
        do {
            let searchResponse = try JSONDecoder().decode(ITunesSearchResponse.self, from: cleanedData)
            if let software = searchResponse.results.first {
                print("软件描述:\(software.iTunesDescription ?? "无描述内容")")
            }
        } catch {
            print("解析错误:\(error)")
        }
    }
    task.resume()
}

// 调用请求方法
fetchRuismakerSoftware()

内容的提问来源于stack exchange,提问作者Gene De Lisa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 02:24:14