使用JSONSerialization.data的JSON中的Swift无效类型写入错误

问题描述

我有一个带有自定义类型元素的数组。这是类型:

public class RequestElemDataBody: Codable {
    public var name: String
    public var value: String

    public init(name: String,value: String) {
        self.name = name
        self.value = value
    }
}

这就是我声明数组的方式:

var elementsInForm = [RequestElemDataBody]()

我使用函数将此数组转换为Data,然后转换为String:

func json(from object: [Any]) -> String? {
    guard let data = try? JSONSerialization.data(withJSONObject: object,options: []) else {
        return nil
    }
    return String(data: data,encoding: String.Encoding.utf8)
}

执行时收到此错误消息:

***由于未捕获的异常'NSinvalidargumentexception'而终止应用程序,原因:'JSON写入中的类型无效(Data.RequestElemDataBody)'

我不知道自定义类型有什么问题,因为它是可编码的。

如何在不引发错误的情况下使用函数解析数组?

解决方法

序列化1>------ Build started: Project: App1,Configuration: Debug Win32 ------ 1> Creating library C:\Users\zxi.BS\source\repos\App1\Debug\App1\App1.lib and object C:\Users\zxi.BS\source\repos\App1\Debug\App1\App1.exp 1>libcrypto.lib(async.obj) : error LNK2019: unresolved external symbol __imp__CreateFiber@12 referenced in function _ASYNC_init_thread 1>libcrypto.lib(async_win.obj) : error LNK2019: unresolved external symbol __imp__ConvertThreadToFiber@4 referenced in function _async_fibre_init_dispatcher 1>C:\Users\zxi.BS\source\repos\App1\Debug\App1\App1.exe : fatal error LNK1120: 2 unresolved externals 1>Done building project "App1.vcxproj" -- FAILED. ========== Build: 0 succeeded,1 failed,0 up-to-date,0 skipped ========== ========== Deploy: 0 succeeded,0 failed,0 skipped ========== 时应使用JSONEncoder

文档页面中的示例:

Codable
,

方法的问题是您尝试对整个数组进行编码。但是您的可编码对象目前还不是数组。

尝试将单个元素传递给您的方法,并在外部返回该字符串以供使用;

func json(from element: RequestElemDataBody) -> String {
...
}
,

here所述,顶级对象可以是Array或Dictionary,所有对象可以是NSString,NSNumber,NSArray,NSDictionary或NSNull的实例。 。在您的情况下,它们是自定义对象的实例。

因此,您可以先尝试将对象转换为字典,然后再使用JSONSerialization

要转换为字典,您可以在Encodable上创建扩展名

    extension Encodable {

    var dict : [String: Any]? {
        guard let data = try? JSONEncoder().encode(self) else { return nil }
        guard let json = try? JSONSerialization.jsonObject(with: data,options: []) as? [String:Any] else { return nil }
        return json
    }
}

在调用函数时,您可以使用ArrayName.compactMap({$ 0.dict})

您还可以使用ObjectMapper库。

引用来自:How to convert a Swift object to a dictionary