英文:
How to rewrite sync method using SwiftUI?
问题
现在我正在使用UIImage同步扩展。
struct PostView: View {
let url: String
var body: some View {
PrivateImageView(image: UIImage(url:url))
}
}
extension UIImage {
public convenience init(url: String) {
let url = URL(string: url)
do {
let data = try Data(contentsOf: url!)
self.init(data: data)!
return
} catch let err {
print("Error : \(err.localizedDescription)")
}
self.init()
}
}
当我发布一张图片时,我收到了错误消息 Synchronous URL loading of http://local.host/images/123.jpeg should not occur on this application's main thread as it may lead to UI unresponsiveness. Please switch to an asynchronous networking API such as URLSession.,出现在 try Data(contentsOf: url!)。
在PostView中,我使用了 PrivateImageView。
要使用这个视图,我必须像这样指定参数 PrivateImageView(image: UIImage(xxxxxxxxx))。
我的意思是,我必须使用 UIImage() 而不是 AsyncImage。
我不知道如何修改 convenience init 来适应 PrivateImageView。
请告诉我如何在这个上下文中使用异步函数。
英文:
Now I'm using UIImage sync extension.
struct PostView: View {
let url: String
var body: some View {
PrivateImageView(image: UIImage(url:url))
}
}
extension UIImage {
public convenience init(url: String) {
let url = URL(string: url)
do {
let data = try Data(contentsOf: url!)
self.init(data: data)!
return
} catch let err {
print("Error : \(err.localizedDescription)")
}
self.init()
}
}
When I post a image, I got the error Synchronous URL loading of http://local.host/images/123.jpeg should not occur on this application's main thread as it may lead to UI unresponsiveness. Please switch to an asynchronous networking API such as URLSession. at try Data(contentsOf: url!).
In PostView I use PrivateImageView.
To use the view I have to designate the argument like this PrivateImageView(image: UIImage(xxxxxxxxx)).
I mean I have to use UIImage() not AsyncImage.
I don't know how to change convenience init to adjust to PrivateImageView.
Please tell me how to use an async function in this context.
答案1
得分: 1
以下是您要翻译的内容:
无法同步从互联网/内网获取数据,您必须使用异步方法并考虑下载所需的时间。
extension String {
public func getUIImage() async throws -> UIImage {
guard let url = URL(string: self) else {
throw URLError(.badURL)
}
let (data, response) = try await URLSession.shared.data(from: url)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
guard httpResponse.statusCode == 200 else {
throw URLError(URLError.Code(rawValue: httpResponse.statusCode))
}
guard let image = UIImage(data: data) else {
throw URLError(.fileDoesNotExist)
}
return image
}
}
extension UIImage {
static public func fromURL(url: String) async throws -> UIImage {
let image = try await url.getUIImage()
return image
}
}
您可以将`PostView`重写为类似以下内容的形式。
struct PostView: View {
let url: String
@State private var uiImage: UIImage?
var body: some View {
Group{
if let uiImage {
PrivateImageView(image: uiImage)
} else {
ProgressView() // 下载时显示此内容
.task {
do {
self.uiImage = try await url.getUIImage()
// 或
// self.uiImage = try await UIImage.fromURL(url: url)
} catch {
print(error)
}
}
}
}
}
}
英文:
There is no way to get a data from the inter/intranet synchronously you have to use an async method and account for the time it takes to download.
extension String {
public func getUIImage() async throws -> UIImage {
guard let url = URL(string: self) else {
throw URLError(.badURL)
}
let (data, response) = try await URLSession.shared.data(from: url)
guard let httpResponse = response as? HTTPURLResponse else {
throw URLError(.badServerResponse)
}
guard httpResponse.statusCode == 200 else {
throw URLError(URLError.Code(rawValue: httpResponse.statusCode))
}
guard let image = UIImage(data: data) else {
throw URLError(.fileDoesNotExist)
}
return image
}
}
extension UIImage {
static public func fromURL(url: String) async throws -> UIImage {
let image = try await url.getUIImage()
return image
}
}
You can rewrite PostView to something like.
struct PostView: View {
let url: String
@State private var uiImage: UIImage?
var body: some View {
Group{
if let uiImage {
PrivateImageView(image: uiImage)
} else {
ProgressView() //Show this while downloading
.task {
do {
self.uiImage = try await url.getUIImage()
// or
// self.uiImage = try await UIImage.fromURL(url: url)
} catch {
print(error)
}
}
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论