Swift4/iOS11.3/Xcode9中嵌套编码JSON字符串遇错的解决方法
解决JSON嵌套编码时的
dataCorrupted错误及单引号转换问题 问题根源
你遇到的dataCorrupted错误,本质是直接把已编码的JSON字符串作为另一个JSON的字段值时,字符串里的双引号会和外层JSON的语法结构冲突。虽然Postman能兼容单引号的非标准JSON,但这并不是规范做法,更可靠的方式是利用结构体嵌套来避免二次编码操作。
最佳解决方案:用结构体嵌套替代二次编码
完全不需要先把OrderDetailJSON编码成字符串,直接修改OrderPlace结构体的字段类型,让order_details直接承载OrderDetailJSON实例,JSONEncoder会自动完成嵌套编码,彻底规避格式冲突:
// 修改OrderPlace结构体的字段类型 struct OrderPlace: Encodable { let apikey: String let ord_store_name: String let ord_amount: String let cust_mob: String let store_id: String let order_details: OrderDetailJSON // 替换为OrderDetailJSON类型 } // 编码流程简化,直接传递结构体实例 do { let taxex = TaxDetail(tax_per: defaults.string(forKey: "STORE_TAX")!, tax_name: defaults.string(forKey: "STORE_TAX_NAME")!) var placeOrder = OrderDetailJSON(TaxDetials: taxex) for item in cartData { let allOre = AllOrder(date_time: item.time, item: "\(item.quantity)", name: item.name, price: "\(item.price)") placeOrder.addOrder(orders: allOre) } // 直接用placeOrder实例初始化OrderPlace let orders = OrderPlace( apikey: "382dfc83", ord_store_name: storeName, ord_amount: "\(finalCartPrice)", cust_mob: defaults.getMobNo(), store_id: storeId, order_details: placeOrder // 传入结构体而非字符串 ) orderPlaceUrl.httpBody = try JSONEncoder().encode(orders) } catch { print("Encode error... \(error)") }
这种方式生成的是标准JSON,order_details字段会自动嵌套内层的完整JSON结构,既不会出现格式错误,也不需要手动处理引号问题,是最推荐的做法。
如果必须转换为单引号(非标准JSON)
如果你因为特殊场景必须将JSON字符串的双引号替换为单引号,可以用字符串替换方法实现:
// 将双引号全局替换为单引号 let singleQuotedJson = jsonString.replacingOccurrences(of: "\"", with: "'") // 使用转换后的字符串初始化OrderPlace let orders = OrderPlace( apikey: "382dfc83", ord_store_name: storeName, ord_amount: "\(finalCartPrice)", cust_mob: defaults.getMobNo(), store_id: storeId, order_details: singleQuotedJson )
⚠️ 注意:这种方式生成的是非标准JSON,虽然Postman能兼容,但很多后端JSON解析器可能无法正确解析,所以仅作为特殊场景的备选方案。
内容的提问来源于stack exchange,提问作者Neck
相关产品推荐
相关产品推荐

