我有很多困难从URL下载图片给我的桌面单元格。我尝试了同步和异步下载,但都没有工作。
对于同步下载,Xcode会给我紫色的警告,图片不会出现在我的表视图中。
警告:
“此应用程序的主线程不应出现同步URL加载.,因为它可能导致UI无响应。请切换到异步网络API (如URLSession)。”
对于异步下载,下载后的代码立即执行,下载无法完成,结果为零。
我该怎么办?
我的代码:
(我正在15个帖子的批次中加载表视图,这是加载批处理的代码)
func reloadBatch(){
for i in currentRow...currentRow+15{
if i == posts.count{
return
}
let post = posts[i] // documens
if post.posttype == 1{
let uP = UIImage(url: URL(string: post.userphoto!)) ?? UIImage(named: "Jordan")
postCell.append(LoadedCellModel(posttype: 1, sender: post.sender, userphoto: uP, title: post.title, photo: nil, videoURL: nil, content: post.content))
}else if post.posttype == 2{
let uP = UIImage(url: URL(string: post.userphoto!)) ?? UIImage(named: "Jordan")
let pic = UIImage(url: URL(string: post.photo![0])) ?? UIImage(named: "Jordan")
// This is the picture that does not show up, "photo" is an array of pictures' URL(in string)
postCell.append(LoadedCellModel(posttype: 2, sender: post.sender, userphoto: uP, title: post.title, photo: pic, videoURL: nil, content: post.content))
print(pic)
}
}
currentRow += 15
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
extension UIImage {
convenience init?(url: URL?) {
guard let url = url else { return nil }
do {
self.init(data: try Data(contentsOf: url))
} catch {
print("Cannot load image from url: \(url) with error: \(error)")
return nil
}
}
}
发布于 2022-09-18 07:51:46
从网络获取数据(如图像)是异步的。也就是说,这需要时间去做。因此,您需要“等待”,直到数据可用,然后才能使用它。注意警告消息...Please switch to an asynchronous networking API such as URLSession
有很多方法可以做到这一点。在这里,我介绍了一种简单的方法,使用带有completion handler
的函数。
这意味着,您不能像在:getImage(url: ..)
中所做的那样使用此函数( let uP = UIImage(url: URL(string: post.userphoto!)) ?? UIImage(named: "Jordan")
)。
你必须使用闭包:
getImage(url: url) { img in
// do something with img
}
下面是下载一个图像的示例代码:
struct ContentView: View {
@State var uimg: UIImage?
let token = "xxxx" // <-- your secret token
var body: some View {
VStack {
if uimg == nil {
Text("downloading")
ProgressView()
} else {
Image(uiImage: uimg!).resizable().frame(width: 333, height: 333)
}
}
.onAppear {
guard let url = URL(string: "https://firebasestorage.googleapis.com/v0/b/pirateforum-f2f04.appspot.com/o/images%2F1663116366.2403781.png?alt=media&token=\(token)") else { return }
getImage(url: url) { img in
self.uimg = img
}
}
}
func getImage(url: URL, completion: @escaping (UIImage?) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data, let img = UIImage(data: data) {
completion(img)
} else {
completion(nil)
}
}.resume()
}
}
请不要在警告信息中显示您的秘密令牌,请删除它。
https://stackoverflow.com/questions/73760498
复制相似问题