首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >valueNotFound:无法将键控解码容器替换为空

valueNotFound:无法将键控解码容器替换为空
EN

Stack Overflow用户
提问于 2020-12-16 16:23:23
回答 1查看 911关注 0票数 0

我的项目包括动态数据,当控制器更改时这些数据会发生变化,因此,有时我的数据可能是:

代码语言:javascript
运行
复制
[
   {
      "callDescription":"TEST 16/12",
      "callDuration":"5-8 Minutes",
      "callID":0,
      "callMade":false,
      "callMade_dateTime":"false_1608151560.0",
      "dateTime":1608044666,
      "type":"Breakfast Call"
   },
     {
      "callDescription":"TEST 16/12",
      "callDuration":"5-8 Minutes",
      "callID":0,
      "callMade":false,
      "callMade_dateTime":"false_1608151560.0",
      "dateTime":1608044666,
      "type":"Breakfast Call"
   },
]

然后运行一段代码,我的数据现在就运行了。

代码语言:javascript
运行
复制
[
   {
      "callDescription":"TEST 16/12",
      "callDuration":"5-8 Minutes",
      "callID":0,
      "callMade":false,
      "callMade_dateTime":"false_1608151560.0",
      "dateTime":1608044666,
      "type":"Breakfast Call"
   },
     null
]

当再次请求数据时,它将导致valueNotFound错误。

跳过/处理任何为null的索引的最佳方法是什么?

下面是我的API代码:

代码语言:javascript
运行
复制
class Service {
    static let shared = Service()
    let BASE_URL = "https://url.com"
    
    func fetchClient(completion: @escaping ([Calls]) -> ()) {

    guard let url = URL(string: BASE_URL) else { return }

    URLSession.shared.dataTask(with: url) { (data, response, error) in

        // handle error
        if let error = error {
            print("Failed to fetch data with error: ", error)
            return
        }

        guard let data = data else {return}

        do {
            let myDecoder = JSONDecoder()
            let calls = try myDecoder.decode([Calls].self, from: data)
            completion(calls)
        } catch let error {
            print("Failed to create JSON with error: ", error)
        }
    }.resume()
}

Calls模型:

代码语言:javascript
运行
复制
struct Calls: Decodable  {
    let callDescription, callDuration, callMade_dateTime: String
    let callID: Int
    let dateTime: Date
    let callMade: Bool
    let type: String
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-16 17:23:05

快速解决方案:

代码语言:javascript
运行
复制
let calls = try myDecoder.decode([Calls].self, from: data)
completion(calls)

=>

代码语言:javascript
运行
复制
let calls = try myDecoder.decode([Calls?].self, from: data)
completion(calls.compactMap{ $0 })

让我们简化这个示例(在编写真正的JSON之前,我开始编写答案):

代码语言:javascript
运行
复制
struct Custom: Codable {
    let data: String
}

let jsonString = """
[{"data": "Hello"}, {"data": "world"}]
"""

let jsonString2 = """
    [{"data": "Hello"}, null, {"data": "world"}]
"""

因此,JSON中的某些值可能为null。那就是我们可以随意使用的地方。

代码语言:javascript
运行
复制
func test(json: String) {
    do {
        print("Testing with [Custom].self: \(json)")
        let customs = try JSONDecoder().decode([Custom].self, from: json.data(using: .utf8)!)
        print("Result: \(customs)")
    } catch {
        print("Error: \(error)")
    }
}

func test2(json: String) {
    do {
        print("Testing with [Custom?].self: \(json)")
        let customs = try JSONDecoder().decode([Custom?].self, from: json.data(using: .utf8)!)
        print("Result with optionals: \(customs)")
        let unwrapped = customs.compactMap { $0 }
        print("Result unwrapped: \(unwrapped)")
    } catch {
        print("Error: \(error)")
    }
}
代码语言:javascript
运行
复制
test(json: jsonString)
test(json: jsonString2)
test2(json: jsonString)
test2(json: jsonString2)

输出:

代码语言:javascript
运行
复制
$>Testing with [Custom].self: [{"data": "Hello"}, {"data": "world"}]
$>Result: [Custom(data: "Hello"), .Custom(data: "world")]
$>Testing with [Custom].self: [{"data": "Hello"}, null, {"data": "world"}]
$>Error: valueNotFound(Swift.KeyedDecodingContainer<.Custom.CodingKeys>, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 1", intValue: 1)], debugDescription: "Cannot get keyed decoding container -- found null value instead.", underlyingError: nil))
$>Testing with [Custom?].self: [{"data": "Hello"}, {"data": "world"}]
$>Result with optionals: [Optional(.Custom(data: "Hello")), Optional(.Custom(data: "world"))]
$>Result unwrapped: [.Custom(data: "Hello"), .Custom(data: "world")]
$>Testing with [Custom?].self: [{"data": "Hello"}, null, {"data": "world"}]
$>Result with optionals: [Optional(.Custom(data: "Hello")), nil, Optional(.Custom(data: "world"))]
$>Result unwrapped: [.Custom(data: "Hello"), .Custom(data: "world")]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65327183

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档