You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:37:49