我无法为 UIImage 进行扩展便利初始化
I can't make extension convenience init for UIImage
我想创建 UIImage(urlString: String?)
。当我 运行 这段代码时没有错误,但它不起作用。
extension UIImage {
convenience init?(urlString: String?) {
var imageData = Data()
guard let urlString = urlString else { return nil}
guard let url = URL(string: urlString) else { return nil}
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("Error: \(error.localizedDescription)")
return
}
guard let response = response as? HTTPURLResponse else {
print("Empty image response")
return
}
print("HTTP image response code: \(response.statusCode)")
guard let data = data else {
print("Empty image data")
return
}
imageData = data
}.resume()
self.init(data: imageData)
}
}
UIImage
initializer init(data:)
是一种同步方法。您的 self.init(data: imageData)
方法在异步方法 dataTask
完成其请求并执行其完成处理程序之前被调用。
我的建议是创建一个扩展 URL
的实例方法并向其添加一个完成处理程序:
extension URL {
func asyncImage(completion: @escaping (UIImage?) -> Void) {
URLSession.shared.dataTask(with: self) { data, _, _ in
guard let data = data, let image = UIImage(data: data) else {
completion(nil)
return
}
completion(image)
}.resume()
}
}
用法:
yourURL.asyncImage { image in
guard let image = image else { return }
// use image here
}
另一种选择是扩展 UIImageView,如此 post
我的解决方案:
- 使用 Data(contentsOf:URL) 从 URL 获取数据,而不是使用 URLSession.dataTask
extension UIImage {
convenience init?(urlString: String) {
self.init()
guard let url = URL(string: urlString), let data = try? Data(contentsOf: url) else { return }
self.init(data: data)
}
}
您必须调用 self.init(),因为它需要在 return 之前调用 self.init()。
因为这是一个 Failable Initializer,如果你的 URL 是有效的,那么你会从那个 URL 中得到一个图像,否则,你会得到 nil。
如果您想在 URL 无效时使用默认图像,只需将 init() 替换为 init(named:):
extension UIImage {
convenience init?(urlString: String) {
self.init(named: "YOUR_IMAGE_NAME")
guard let url = URL(string: urlString), let data = try? Data(contentsOf: url) else { return }
self.init(data: data)
}
}
我想创建 UIImage(urlString: String?)
。当我 运行 这段代码时没有错误,但它不起作用。
extension UIImage {
convenience init?(urlString: String?) {
var imageData = Data()
guard let urlString = urlString else { return nil}
guard let url = URL(string: urlString) else { return nil}
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("Error: \(error.localizedDescription)")
return
}
guard let response = response as? HTTPURLResponse else {
print("Empty image response")
return
}
print("HTTP image response code: \(response.statusCode)")
guard let data = data else {
print("Empty image data")
return
}
imageData = data
}.resume()
self.init(data: imageData)
}
}
UIImage
initializer init(data:)
是一种同步方法。您的 self.init(data: imageData)
方法在异步方法 dataTask
完成其请求并执行其完成处理程序之前被调用。
我的建议是创建一个扩展 URL
的实例方法并向其添加一个完成处理程序:
extension URL {
func asyncImage(completion: @escaping (UIImage?) -> Void) {
URLSession.shared.dataTask(with: self) { data, _, _ in
guard let data = data, let image = UIImage(data: data) else {
completion(nil)
return
}
completion(image)
}.resume()
}
}
用法:
yourURL.asyncImage { image in
guard let image = image else { return }
// use image here
}
另一种选择是扩展 UIImageView,如此 post
我的解决方案:
- 使用 Data(contentsOf:URL) 从 URL 获取数据,而不是使用 URLSession.dataTask
extension UIImage {
convenience init?(urlString: String) {
self.init()
guard let url = URL(string: urlString), let data = try? Data(contentsOf: url) else { return }
self.init(data: data)
}
}
您必须调用 self.init(),因为它需要在 return 之前调用 self.init()。 因为这是一个 Failable Initializer,如果你的 URL 是有效的,那么你会从那个 URL 中得到一个图像,否则,你会得到 nil。
如果您想在 URL 无效时使用默认图像,只需将 init() 替换为 init(named:):
extension UIImage {
convenience init?(urlString: String) {
self.init(named: "YOUR_IMAGE_NAME")
guard let url = URL(string: urlString), let data = try? Data(contentsOf: url) else { return }
self.init(data: data)
}
}