JSON编码带有数组的Swift对象时,异常“ JSON写入(__SwiftValue)中的类型无效”

时间:2019-12-02 02:16:10

标签: ios json swift

在尝试将此Swift对象编码为JSON时获取异常cv.notify_all()。所有非可选成员,可编码对象。什么是正确的编码方式或应该使用一些第三方库?

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__SwiftValue)'

1 个答案:

答案 0 :(得分:1)

问题是您使用的是JSONSerialization而不是JSONEncoderJSONSerialization是将对象写入JSON的较旧的Foundation / Objective-C方法。它将仅适用于Foundation对象(有关完整列表,请参见documentation)。

您应该使用JSONEncoder。棘手的部分是,JSONEncoder无法在无需您做任何工作的情况下直接对Dictionary进行编码。有几种方法可以解决此问题,但是如果这是您将要使用的唯一JSON格式,则可能只需要使用CodingKeys为您的结构创建自定义键即可。

struct MediaItem: Codable {
    var key: String = ""
    var filename: String = ""
}

struct NoteTask: Codable {
    var id: String = ""
    var notes: String = ""
    var mediaList: [MediaItem] = []

    enum CodingKeys: String, CodingKey {
        case id = "email"
        case notes = "notes"
        case mediaList = "fileList"
    }
}

static func addTask(task: NoteTask, callback: @escaping TaskAPICallback) {
    let configuration = URLSessionConfiguration.default
    let session = URLSession(configuration: configuration)

    let url = URL(string: postUrl)
    var request : URLRequest = URLRequest(url: url!)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    do {
        request.httpBody = try JSONEncoder().encode(task)
    } catch {
        DispatchQueue.main.async {
            callback(false)
        }
        return
    }
}