API 响应中的一个错误是给我一个字段,有时是整数,有时是字符串。如何将其转换为一种一致的类型?[复制]

A bug in an API response is giving me a field sometimes as integer, and sometimes string. How do I convert this to one consistent type? [duplicate]

提问人:swdr 提问时间:8/1/2023 最后编辑:Brian Tompsett - 汤莱恩swdr 更新时间:8/1/2023 访问量:31

问:

我正在和一位同事一起用 Swift 开发一个 iOS 应用程序。

我有一个 API 用于从服务器检索一些聊天。每个聊天都有一个字段。我希望这是一个字符串,但 API 有时会将其作为整数提供给我。下面是 JSON 的示例:message_id

[
    {
        "id": 17,
        "message_id": "434",
        "last_sender_id": "121",
        "subject": {
            "rendered": "Re: No Subject"
        },
        "excerpt": {
            "rendered": "very good"
        },
        "message": {
            "rendered": "<p>very good</p>\n"
        },
        "date": "2023-06-21T14:32:47",
    },
    {
        "id": 17,
        "message_id": 430,
        "last_sender_id": "121",
        "subject": {
            "rendered": "Re: No Subject"
        },
        "excerpt": {
            "rendered": "Hi"
        },
        "message": {
            "rendered": "<p>Hi</p>\n"
        },
        "date": "2022-11-18T15:20:13",
    },
    {
        "id": 17,
        "message_id": "428",
        "last_sender_id": "121",
        "subject": {
            "rendered": "No Subject"
        },
        "excerpt": {
            "rendered": "Test"
        },
        "message": {
            "rendered": "<p>Test</p>\n"
        },
        "date": "2022-11-18T15:19:10",
    },
]

API 提供商已确认这是将来要修复的错误,但我现在必须找到解决方法。我问我的同事,在使用它时,我们能不能不把类型从 int 转换为 string?(我不是 Swift 专家)。他们说:

“这不是工作原理,因为我是从JSON获取的,我必须在所有对象解压缩之前告诉转换器会发生什么”。message_id

他们说的对吗?如何解决此错误?

调用了 API。它有时给出 as 字符串,有时给出整数。这是我现在需要解决的一个错误,直到提供商修复它。我已经用我的同事所说的话更新了 OP。message_id

iOS JSON 斯威夫特

评论

0赞 Kudos 8/1/2023
理想情况下,它应该具有单一数据类型,但如果您获得的是动态数据类型,则可以使用: var message_id = AnyAny
0赞 Fogmeister 8/1/2023
与后端开发人员交谈并要求他们修复它 😅
0赞 swdr 8/1/2023
@Kudos介意发布一个他们如何使用的例子吗?他们坚持认为,“在所有物品被拆开之前,我必须告诉转换器会发生什么”。Any
0赞 swdr 8/1/2023
@Fogmeister我有 - 他们说没有承诺的修复时间表,但我的开发被搁置了,这就是为什么我现在需要有一个解决方法!
0赞 Fogmeister 8/1/2023
@swdr不用担心。我只是半开玩笑。另外,不要使用 .应尽可能避免使用 Any。Any

答:

0赞 ytshen 8/1/2023 #1

您可以自定义方法以区分特定类型(尽管不建议使用此方法)。init(from decoder: Decoder)

struct S: Codable {
    var id: String
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        if let strId = try? container.decode(String.self, forKey: .id) {
            self.id = strId
        } else if let intId = try? container.decode(Int.self, forKey: .id) {
            self.id = "\(intId)"
        } else {
            fatalError("")
        }
    }
}

let jsonWithStr = "{\"id\":\"11\"}".data(using: .utf8)!
let jsonWithInt = "{\"id\":11}".data(using: .utf8)!

print(try JSONDecoder().decode(S.self, from: jsonWithStr))
print(try JSONDecoder().decode(S.self, from: jsonWithInt))

评论

0赞 swdr 8/1/2023
谢谢你,你能说说为什么不推荐吗?在修复 API 之前,将其用作解决方法会带来什么影响?
0赞 ytshen 8/1/2023
将该值修复为具有单个类型是最佳解决方案。