英文:
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)
}
}
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论