Swift 4中嵌套JSON转Data对象及URLRequest请求体处理疑问
解决JSONSerialization转Data失败及_SwiftValue错误的问题
嘿,我之前处理APNs推送请求时碰到过一模一样的问题,来帮你拆解核心问题和解决办法:
问题根源分析
你遇到的两个错误其实是两个独立的坑:
- 第一个坑:
JSONSerialization只能处理Foundation原生类型(String、Int、Double、Array、Dictionary、nil等),UIImage是Swift对象类型,根本不在JSON支持的类型列表里,直接放进去必然导致isValidJSONObject返回false。 - 第二个坑:你写的
"data" : { // Add optional data here. }是非法的Swift字典字面量写法——空字典应该用[:]或者[String: Any](),直接写{}会被Swift解析成未指定类型的匿名块,最终变成_SwiftValue类型,这也是JSON序列化失败的关键原因。
分步解决方案
1. 把UIImage转成Base64字符串
先将图片转成Data,再编码成Base64字符串,注意处理可选值(避免图片转Data失败导致的nil):
// 假设你的icon是UIImage实例 guard let iconData = icon.pngData(), let iconBase64 = iconData.base64EncodedString(options: .endLineWithLineFeed) else { // 处理图片转Data失败的情况 fatalError("Failed to convert icon to Base64") }
若需要更小的体积,可以用
jpegData(compressionQuality: 0.8)代替pngData(),根据需求调整压缩质量。
2. 构建合法的JSON字典
修正所有非法类型和语法错误,确保所有值都是Foundation支持的类型:
// 先处理可选的data部分,用合法的空字典初始化 var optionalData: [String: Any] = [:] // 这里可以添加自定义数据,比如: // optionalData["custom_key"] = "custom_value" // optionalData["badge_count"] = 1 // 构建完整的JSON字典 let json: [String: Any] = [ "to": toDeviceToken, // String,合法 "notification": [ "title": title, // String,合法 "body": body, // String,合法 "icon": iconBase64 // Base64字符串,合法 ], "data": optionalData // 合法的空字典或自定义字典 ]
3. 序列化成Data并处理错误
现在可以安全地用JSONSerialization转成Data了,记得处理可能的错误:
var request = URLRequest(url: yourAPNsURL) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") do { let jsonData = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted) request.httpBody = jsonData } catch { print("JSON序列化失败:\(error.localizedDescription)") // 这里可以添加错误处理逻辑 }
额外检查点
- 确保
toDeviceToken、title、body都是非nil的String类型,若允许nil,要转成NSNull()。 - 若在
data里添加自定义值,也要确保都是Foundation支持的类型,别放Swift的自定义结构体/类。
内容的提问来源于stack exchange,提问作者j3141592653589793238
相关产品推荐
相关产品推荐

