【问题标题】:Catching NSJSONSerialization errors in Swift在 Swift 中捕获 NSJSONSerialization 错误
【发布时间】:2017-03-19 23:30:52
【问题描述】:

我试图了解为什么我无法捕获 NSJSONSerialization 引发的错误。

我希望引发和捕获 NSInvalidArgumentException 异常,但应用程序却崩溃了。

这在使用 Xcode 8 的 Swift 3 和 Swift 2.3 中都会发生。

斯威夫特 3:

    do {
        _ = try JSONSerialization.data(withJSONObject: ["bad input" : NSDate()])
    }
    catch {
        print("this does not print")
    }

Swift 2.3:

    do {
        _ = try NSJSONSerialization.dataWithJSONObject(["bad input" : NSDate()], options: NSJSONWritingOptions())
    }
    catch {
        print("this does not print")
    }

这段代码放在一个空白 Xcode 项目中的 applicationDidFinishLaunching 中。在模拟器和设备上测试。

完全例外:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (__NSDate)'

任何想法为什么 catch 块没有捕捉到这个特定的错误?

【问题讨论】:

  • do/try/catch 捕获 swift 错误,而不是 Objective-c 异常。
  • 这是一个编程错误。它应该崩溃。 NSDate 不是有效的 JSON 类型。修复编程错误。
  • 我正在制作一个接受 JSON 对象作为参数的 API,所以我在编译时不知道它会得到什么输入。看起来唯一的解决方案是连接到 Objective-C 领域以捕获那里的异常。我也会考虑使用isValidJSONObject
  • 我只是不明白为什么我在网上看到的所有教程都为此使用 do/catch 模式。 Swift catch 块是否会捕获来自 NSJSONSerialization 的任何类型的错误?
  • 所有教程都使用try,因为dataWithJSONObject被声明为throws。不幸的是,文档非常模糊。关于“内部错误”的一些事情。但是使用isValidJSONObject 是您想要的,因为它可以避免NSInvalidArgumentException 问题。无需桥接到 Objective-C。

标签: ios swift foundation


【解决方案1】:

来自JSONSerialization data(withJSONObject:options:)的文档:

如果 obj 不会生成有效的 JSON,则会引发异常。此异常在解析之前抛出,表示编程错误,而不是内部错误。在调用此方法之前,您应该使用 isValidJSONObject(_:) 检查输入是否会生成有效的 JSON。

这意味着您无法捕获由无效数据引起的异常。 catch 块中只能捕获“内部错误”(无论其实际含义)。

为避免可能出现的NSInvalidArgumentException,您需要使用isValidJSONObject

然后你的代码变成:

do {
    let obj = ["bad input" : NSDate()]
    if JSONSerialization.isValidJSONObject(obj) {
        _ = try JSONSerialization.data(withJSONObject: obj)
    } else {
        // not valid - do something appropriate
    }
}
catch {
    print("Some vague internal error: \(error)")
}

【讨论】:

  • 实际会抛出什么样的错误?似乎我应该将try? 与 JSONSerialization 一起使用。
  • @Michael 如果您不想修复您的编程错误,请仅使用try?
  • 消极是没有效率的。对于其他想知道的人,这里是显示所有错误可能性的来源:github.com/apple/swift-corelibs-foundation/blob/master/…
  • @MichaelOzeryansky 我不是消极的。你说你应该只使用try?,我明确表示你不想忽略这个错误。现有答案显示了文档中的引用,解释了您为什么不想忽略异常。
猜你喜欢
  • 2016-09-25
  • 1970-01-01
  • 2015-10-06
  • 2016-01-10
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多