首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从URL下载Tableview单元格图片时出错

从URL下载Tableview单元格图片时出错
EN

Stack Overflow用户
提问于 2022-09-18 06:11:44
回答 1查看 223关注 0票数 0

我有很多困难从URL下载图片给我的桌面单元格。我尝试了同步和异步下载,但都没有工作。

对于同步下载,Xcode会给我紫色的警告,图片不会出现在我的表视图中。

警告:

“此应用程序的主线程不应出现同步URL加载.,因为它可能导致UI无响应。请切换到异步网络API (如URLSession)。”

对于异步下载,下载后的代码立即执行,下载无法完成,结果为零。

我该怎么办?

我的代码:

(我正在15个帖子的批次中加载表视图,这是加载批处理的代码)

代码语言:javascript
运行
复制
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
    }
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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") )。

你必须使用闭包:

代码语言:javascript
运行
复制
 getImage(url: url) { img in
     // do something with img
 }

下面是下载一个图像的示例代码:

代码语言:javascript
运行
复制
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()
    }
}

请不要在警告信息中显示您的秘密令牌,请删除它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73760498

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档