Swift JSON 中的无效类型使用 JSONSerialization.data 写入错误
Swift Invalid type in JSON write error using JSONSerialization.data
我有一个包含自定义类型元素的数组。这是类型:
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]()
我使用函数将此数组转换为数据,然后再转换为字符串:
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)
}
执行时收到此错误消息:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (Data.RequestElemDataBody)'
我不知道我的自定义类型有什么问题,因为它是 Codable。
如何使用我的函数解析我的数组而不抛出错误?
序列化Codable
时应该使用JSONEncoder
。
文档页面中的示例:
struct GroceryProduct: Codable {
var name: String
var points: Int
var description: String?
}
let pear = GroceryProduct(name: "Pear", points: 250, description: "A ripe pear.")
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(pear)
print(String(data: data, encoding: .utf8)!)
/* Prints:
{
"name" : "Pear",
"points" : 250,
"description" : "A ripe pear."
}
*/
您的方法存在问题,您尝试对整个数组进行编码。但是您的可编码对象目前不是数组。
尝试将单个元素传递给您的方法,并return要在外部使用它的字符串;
func json(from element: RequestElemDataBody) -> String {
...
}
如前所述here 顶级对象可以是数组或字典,所有对象都可以是 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 库。
参考资料来自:
我有一个包含自定义类型元素的数组。这是类型:
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]()
我使用函数将此数组转换为数据,然后再转换为字符串:
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)
}
执行时收到此错误消息:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (Data.RequestElemDataBody)'
我不知道我的自定义类型有什么问题,因为它是 Codable。
如何使用我的函数解析我的数组而不抛出错误?
序列化Codable
时应该使用JSONEncoder
。
文档页面中的示例:
struct GroceryProduct: Codable {
var name: String
var points: Int
var description: String?
}
let pear = GroceryProduct(name: "Pear", points: 250, description: "A ripe pear.")
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(pear)
print(String(data: data, encoding: .utf8)!)
/* Prints:
{
"name" : "Pear",
"points" : 250,
"description" : "A ripe pear."
}
*/
您的方法存在问题,您尝试对整个数组进行编码。但是您的可编码对象目前不是数组。
尝试将单个元素传递给您的方法,并return要在外部使用它的字符串;
func json(from element: RequestElemDataBody) -> String {
...
}
如前所述here 顶级对象可以是数组或字典,所有对象都可以是 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 库。
参考资料来自: