下载图片时无法获取UIImage,guard let img校验后触发completionHandler(.notcompleted)
问题排查与修复方案
触发UIImage(data: dt)校验失败的常见原因
- 返回数据不是有效图片格式:服务器返回的实际内容是错误页面、JSON报错信息、防盗链拦截提示等非图片数据,虽然拿到了Data实例但不符合UIImage可识别的编码规范
- 请求响应异常:HTTP状态码为4xx/5xx、重定向未被正确处理,返回的Data是异常响应的内容
- 图片格式不兼容:iOS原生UIImage默认不支持WebP、部分特殊压缩格式的图片,解码失败
- 隐含代码问题:当前所有
completionHandler回调都在后台线程触发,若回调内直接操作UI会触发不可预期的异常
排查方式
在guard let dt = data代码后新增调试逻辑,确认返回内容有效性:
// 打印状态码和数据长度辅助排查 if let httpRes = response as? HTTPURLResponse { print("请求状态码:\(httpRes.statusCode)") } print("返回数据长度:\(dt.count)") // 可将data写入沙盒导出,直接验证是否为有效图片
如果状态码非200、数据长度远小于正常图片大小,优先排查请求链接有效性、服务器鉴权/防盗链配置。
修复后代码
func downloadImage(urlStr : String , completionHandler : @escaping (DownloadImage) -> Void) { // 首次回调切到主线程,避免调用方操作UI异常 DispatchQueue.main.async { completionHandler(.serviceStarts) } guard let url = URL(string: urlStr) else { DispatchQueue.main.async { completionHandler(.notcompleted) } return } let dataTask = URLSession.shared.dataTask(with: url) { data, response, error in // 统一切主线程回调 DispatchQueue.main.async { // 先校验请求无错误、状态码为200 guard error == nil, let httpRes = response as? HTTPURLResponse, httpRes.statusCode == 200, let dt = data else{ completionHandler(.notcompleted) return } guard let img = UIImage(data: dt) else { completionHandler(.notcompleted) return } completionHandler(.successful(img)) } } dataTask.resume() } enum DownloadImage { case serviceStarts case notcompleted case successful(UIImage) }
如果确认返回的是WebP等特殊格式图片,需要引入第三方解码库完成图片解码后再生成UIImage实例。
内容的提问来源于stack exchange,提问作者Rajat
相关产品推荐
相关产品推荐

