如何从URL Swift数组中检索图像数组

问题描述

我正在尝试从网址数组中检索图像。

我有这个功能,但不能正常工作,所以我尝试使用URLSession,但不知道该怎么做>>

func downloadImages(imageUrls: [String],completion: @escaping (_ images: [UIImage?]) -> Void) {
        
    var imageArray: [UIImage] = []
    var downloadCounter = 0
    
    for link in imageUrls {
        let url = NSURL(string: link)
        let  downloadQueue = dispatchQueue(label: "imageDowmloadQueue")
        
        downloadQueue.sync {
            downloadCounter += 1
            let data = NSData(contentsOf: url! as URL)
            
            if data != nil {
                //image data ready and need to be converted to UIImage
                imageArray.append(UIImage(data: data! as Data)!)
                
                if downloadCounter == imageArray.count {
                    dispatchQueue.main.async {
                        completion(imageArray)
                        
                    }
                }
            } else {
                print("Couldnt download image")
                completion(imageArray)
            }
        }
    }
}

我正在使用的功能

public func imagesFromURL(urlString: [String],completion: @escaping (_ images: [UIImage?]) -> Void) {
        
        var imageArray: [UIImage] = []
        var downloadCounter = 0
        let  downloadQueue = dispatchQueue(label: "imageDowmloadQueue")

        for link in urlString {
            downloadQueue.sync {
            downloadCounter += 1
        let dataTask = URLSession.shared.dataTask(with: NSURL(string: link)! as URL,completionHandler: { (data,response,error ) in

            if error != nil {
                print(error ?? "No Error")
                return
            }
            
            if data != nil {
                imageArray.append(UIImage(data: data! as Data)!)
                if downloadCounter == imageArray.count {
                    completion(imageArray)

                    }
                } else {
                            print("Couldnt download image")
                            completion(imageArray)
                           }
                
            } dataTask.resume()
                }
            }
}

我想调用集合单元中的函数,并仅从每个图稿阵列中获得第一张图像的显示


        //download the first image only to display it:
        if artwork.ImgLink != nil && artwork.ImgLink.count > 0 {
            
            downloadImages(imageUrls: [artwork.ImgLink.first!]) { (images) in
                self.artworkImage.image = images.first as? UIImage
            }
        }

解决方法

  1. 如果打算仅使用URL数组中的第一个可用UIImage,则不要设计一个试图下载所有URL的函数。相反,尝试从第一个URL下载,如果下载成功,则返回下载的UIImage,如果失败,则返回第二个URL,重复直到获得UIImage
  2. 在本地函数中创建DispatchQueue对我来说似乎很危险。一种更常见的做法是在其他地方维护队列,并将其作为参数传递给函数,或者,如果没有特殊原因,则使用DispatchQueue.global(qos:)重用预定义的全局队列之一。
  3. 请注意syncsync阻塞调用线程,直到您的阻塞在队列中完成为止。通常,您使用async
  4. 使用Int计数器来控制何时完成多个异步任务(何时调用完成块),但是可以通过使用DispatchGroup来改进,firstImage(inURLs:completion:)可以简单明了地处理多个异步任务方式。

这是两个功能。两者都可以。 UIImage仅返回成功下载的第一个images(forURLs:completion:)func firstImage(inURLs urls: [String],completion: @escaping (UIImage?) -> Void) { DispatchQueue.global().async { for urlString in urls { if let url = URL(string: urlString) { if let data = try? Data(contentsOf: url),let image = UIImage(data: data) { DispatchQueue.main.async { completion(image) } return } } } DispatchQueue.main.async { completion(nil) } } } // Use it. firstImage(inURLs: artwork.ImgLink) { image in self.artworkImage.image = image } 尝试下载并全部返回。

func images(forURLs urls: [String],completion: @escaping ([UIImage?]) -> Void) {
    let group = DispatchGroup()
    var images: [UIImage?] = .init(repeating: nil,count: urls.count)
    
    for (index,urlString) in urls.enumerated() {
        group.enter()
        DispatchQueue.global().async {
            var image: UIImage?
            if let url = URL(string: urlString) {
                if let data = try? Data(contentsOf: url) {
                    image = UIImage(data: data)
                }
            }
            images[index] = image
            group.leave()
        }
    }
    
    group.notify(queue: .main) {
        completion(images)
    }
}

// Use it.
images(forURLs: artwork.ImgLink) { images in
    self.artworkImage.image = images.first(where: { $0 != nil }) ?? nil
}
https://smap.cas.mcmaster.ca/wp-admin/post.php?post=1035&action=edit