使用Swift 4加载外部图像时,如果URL在下面的代码块中以非200响应进行响应,则会遇到问题。例如,在提供发送401的图像时,应用程序在此示例的第2行崩溃,并出现以下错误:
Thread 29: Fatal error: Unexpectedly found nil while unwrapping an Optional value
如何解决此问题并提供其他网址?
let imageUrl:URL = URL(string: imageUrlString)!
let imageData:NSData = NSData(contentsOf: imageUrl)!
let imageView = UIImageView(frame: CGRect(x:11, y:90, width:80, height:80))
// When from background thread, UI needs to be updated on main_queue
DispatchQueue.main.async {
let image = UIImage(data: imageData as Data)
imageView.image = image
imageView.layer.zPosition = 1
imageView.contentMode = UIViewContentMode.scaleAspectFit
self.view.addSubview(imageView)
}
答案 0 :(得分:1)
来自NSData(contentsOf:
文档(遗憾的是Data
中缺少此注释):
因此,请认真对待此说明并使用URLSession
guard let imageUrl = URL(string: imageUrlString) else { // ... handle the `nil` case }
let task = URLSession.shared.dataTask(with: imageUrl) { data, response, error in
if let error = error { print(error); return }
guard let response = response as? HTTPURLResponse else { print("Response is not HTTPResponse"); return }
if response.statusCode != 200 { print("response error:", response.statusCode); return }
DispatchQueue.main.async {
let image = UIImage(data: data!) // `data` can be unwrapped safely if `error` is nil
imageView.image = image
imageView.layer.zPosition = 1
imageView.contentMode = .scaleAspectFit
self.view.addSubview(imageView)
}
}
task.resume()
您可以单独处理error
和response
。如果error
为nil
,则data
为非零,反之亦然。
答案 1 :(得分:0)
NSData(contentsOf:url)是一个可用的初始化器,这意味着它返回一个可选的NSData实例,并且它失败的一个实例是非200响应。
然后,您的代码尝试使用'!'强行解开它。这就是你得错的原因。
首先,你需要决定如果它失败了怎么办,即你不打算显示图像,显示默认图像等等。
然后更改您的代码以考虑到这一点。所以像这样:
let imageUrl:URL = URL(string: imageUrlString)!
if let imageData = NSData(contentsOf: imageUrl) {
let imageView = UIImageView(frame: CGRect(x:11, y:90, width:80, height:80))
// When from background thread, UI needs to be updated on main_queue
DispatchQueue.main.async {
let image = UIImage(data: imageData as Data)
imageView.image = image
imageView.layer.zPosition = 1
imageView.contentMode = UIViewContentMode.scaleAspectFit
self.view.addSubview(imageView)
}
} else {
// Do whatever you want if getting the image fails, e.g. non 200 response.
}
修改强>
正如已经指出的那样,NSData(contentsOf :)不应该用于网络相关的查询,但即使对于本地查询,它仍然可能失败,所以我会留下答案,因为这是原始错误的原因。