在从文件中读取 JSON 数据的以下场景中,我有以下代码块:
// Fetch URL
let url = Bundle.main.url(forResource: "sampleJSON", withExtension: "json")!
// Load Data
let data = try! Data(contentsOf: url)
// Deserialize JSON
let json = try! JSONSerialization.jsonObject(with: data, options: [])
这个代码块本身是正确的,还是将它包含在 do-catch block 中会更好?我问是因为我看到了使用 URLSession 从 Web 中提取数据的场景,其中开发人员在 do-catch block 内执行 JSONSerialization。为什么在使用 URLSession 时这样做,而不是在简单地从文件中提取 JSON 数据时这样做?像这样的最佳做法是什么?
最佳答案
1 - 这个代码块本身是否正确,或者将它包含在 do-catch block 中是否更好?
答:这段代码是正确的。如果您的 sampleJSON.json
文件在您的包中并且您的 JSON 文件中的数据格式正确并且 JSONSerialization,它将起作用
成功解析提供的数据。
2 - 我问这个问题是因为我看到了使用 URLSession 从 Web 中提取数据的场景,其中开发人员在 do-catch block 内执行 JSONSerialization。为什么在使用 URLSession 时这样做,而不是在简单地从文件中提取 JSON 数据时这样做?像这样的最佳做法是什么?
答:当从网络上使用数据(在本例中为 JSON)时,do-catch 语句更常见,因为 API 可能因任何原因(必须显示的数据的错误规范、网络应用程序中的错误)而中断本身等),如果发生这种情况,我们不希望我们的应用程序崩溃。
我说 CRASH 是因为您使用了 !
,它不会将错误传播到应用程序的上层,它会尝试强制操作,如果失败会使应用程序崩溃。
在这一点上,您可能已经意识到在使用包中的数据时看不到 do-catch 语句的原因是因为应用程序开发人员自己提供了 JSON,所以我假设您确定文件的内容,但我仍然会使用 do-catch 语句,因为可能会出现问题并且不希望我的应用程序因这样的愚蠢事情而崩溃。
长话短说
我建议始终使用 throws/rethrows 甚至 ?
的错误传播,这样您就可以测试 nil 结果。
我写了一个small article here一些技巧以及它在 Swift 2.1 中的工作原理,在 Swift 3.1 中变化不大,因此您可以用来研究 do-catch 语句。
我会像这样重写您提供的代码:
警告:未经测试的代码
enum JSONFromFileError: Error {
case fileNotInBundle(String)
case deserializationError
case getDataError(URL)
}
func json(from file: String) throws -> Any {
// Fetch URL in Bundle
guard let url = Bundle.main.url(forResource: file, withExtension: "json") else {
throw JSONFromFileError.fileNotInBundle(file)
}
// Load Data from url
guard let data = try? Data(contentsOf: url) else {
throw JSONFromFileError.getDataError(url)
}
// Deserialize JSON
guard let json = try? JSONSerialization.jsonObject(with: data, options: []) else {
throw JSONFromFileError.deserializationError
}
return json
}
do {
let myJsonObject = try json(from: "sampleJSON")
print(myJsonObject)
} catch let error {
print(error)
}
关于ios - 何时使用 Swift 使用 do-catch block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44808214/