如何在iOS(Swift)与Android中判断JSON的order_id值为字符串或整数
嘿,这个问题我之前帮不少移动端新手踩过坑!后端返回JSON时字段类型不统一确实挺闹心的,不过别慌,iOS(Swift)和Android平台都有成熟的解决办法,我给你详细说说:
iOS (Swift) 处理方案
不管是用手动解析还是Codable序列化,都能轻松处理这种类型不一致的情况:
方法1:手动解析(JSONSerialization)
适合不想引入第三方库的场景,直接判断字段类型再转换:
// 假设jsonString是后端返回的JSON字符串 if let jsonData = jsonString.data(using: .utf8) { do { guard let rootJson = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any], let orders = rootJson["orders"] as? [[String: Any]] else { print("JSON结构不符合预期") return } for order in orders { // 核心:判断order_id的类型 let orderId: Int if let idStr = order["order_id"] as? String { // 字符串类型转Int,记得处理转换失败的情况 guard let convertedId = Int(idStr) else { print("order_id字符串无法转成Int: \(idStr)") continue } orderId = convertedId } else if let idInt = order["order_id"] as? Int { // 整数类型直接使用 orderId = idInt } else { print("order_id类型未知") continue } // 处理其他字段 let invoiceId = order["invoice_id"] as? String let orderStatus = order["order_status"] as? String print("Order ID: \(orderId), Invoice ID: \(invoiceId ?? "无")") } } catch { print("JSON解析错误: \(error.localizedDescription)") } }
方法2:Codable自定义解析器
如果项目用Codable做序列化,可以自定义解码逻辑,自动适配两种类型:
struct Order: Codable { var orderId: Int var invoiceId: String? var orderStatus: String? // 映射JSON字段名 enum CodingKeys: String, CodingKey { case orderId = "order_id" case invoiceId = "invoice_id" case orderStatus = "order_status" } // 自定义解码逻辑 init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 先尝试解析成Int,失败就解析成String再转Int do { orderId = try container.decode(Int.self, forKey: .orderId) } catch DecodingError.typeMismatch { let idStr = try container.decode(String.self, forKey: .orderId) guard let convertedId = Int(idStr) else { throw DecodingError.dataCorruptedError( forKey: .orderId, in: container, debugDescription: "order_id无法转换为Int类型" ) } orderId = convertedId } // 解析其他可选字段 invoiceId = try container.decodeIfPresent(String.self, forKey: .invoiceId) orderStatus = try container.decodeIfPresent(String.self, forKey: .orderStatus) } } // 使用示例 let decoder = JSONDecoder() do { // 假设jsonData是后端返回的Data类型 let response = try decoder.decode([String: [Order]].self, from: jsonData) if let orders = response["orders"] { orders.forEach { order in print("Order ID: \(order.orderId)") } } } catch { print("Codable解析失败: \(error)") }
Android 处理方案
Android平台常用的JSONObject手动解析和Gson序列化都能解决这个问题:
方法1:JSONObject手动判断类型
原生API就能搞定,直接判断字段的类型再转换:
// 假设jsonString是后端返回的JSON字符串 try { val rootObj = JSONObject(jsonString) val ordersArray = rootObj.getJSONArray("orders") for (i in 0 until ordersArray.length()) { val orderObj = ordersArray.getJSONObject(i) // 核心:判断order_id的类型 val orderId: Int = when (val value = orderObj.get("order_id")) { is String -> { // 字符串转Int,处理转换异常 try { value.toInt() } catch (e: NumberFormatException) { println("order_id字符串转Int失败: $value") -1 // 异常情况返回默认值 } } is Int -> value else -> { println("order_id类型未知") -1 } } // 获取其他字段,用optString避免字段不存在抛出异常 val invoiceId = orderObj.optString("invoice_id") val orderStatus = orderObj.optString("order_status") println("Order ID: $orderId, Invoice ID: $invoiceId") } } catch (e: JSONException) { e.printStackTrace() }
方法2:Gson自定义TypeAdapter
如果项目用Gson做序列化,写一个自定义适配器自动处理类型转换:
// 自定义TypeAdapter,处理order_id的类型转换 class OrderIdTypeAdapter : TypeAdapter<Int>() { override fun write(out: JsonWriter, value: Int?) { out.value(value) } override fun read(`in`: JsonReader): Int { return when (`in`.peek()) { // 如果是字符串,转成Int JsonToken.STRING -> `in`.nextString().toInt() // 如果是数字,直接取Int JsonToken.NUMBER -> `in`.nextInt() // 其他类型跳过并返回默认值 else -> { `in`.skipValue() -1 } } } } // 定义Order数据类 data class Order( // 给order_id字段绑定自定义适配器 @JsonAdapter(OrderIdTypeAdapter::class) @SerializedName("order_id") val orderId: Int, @SerializedName("invoice_id") val invoiceId: String?, @SerializedName("order_status") val orderStatus: String? ) // 使用示例 val gson = GsonBuilder() .registerTypeAdapter(Int::class.java, OrderIdTypeAdapter()) .create() try { val rootObj = JSONObject(jsonString) val ordersJson = rootObj.getJSONArray("orders").toString() val orders = gson.fromJson(ordersJson, Array<Order>::class.java) orders.forEach { order -> println("Order ID: ${order.orderId}") } } catch (e: Exception) { e.printStackTrace() }
小提示:不管用哪种方法,建议统一把order_id转成同一种类型(比如Int)存储和使用,避免后续业务逻辑里出现类型判断的冗余代码~
内容的提问来源于stack exchange,提问作者Gorakh Yadav
相关产品推荐
相关产品推荐

