如何从 url swift 数组中检索图像数组

How to retrieve array of images from array of url swift

我正在尝试从 url..

数组中检索图像

我有这个功能和我不会做的一样,但它不起作用,所以我尝试使用 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、return 下载已下载的 UIImage,或者如果失败则继续第二个 url,重复直到获得 UIImage.
  2. 在本地函数中创建 DispatchQueue 对我来说很危险。一种更常见的做法是在其他地方维护一个队列并将其作为参数传递给函数,或者如果没有特定原因,可以使用 DispatchQueue.global(qos:) 重用预定义的全局队列之一。
  3. 小心syncsync 阻塞调用线程,直到您的块在队列中完成。通常你使用 async.
  4. 使用 Int 计数器来控制何时完成多个异步任务(何时调用完成块)是可行的,但可以通过使用 DispatchGroup 来改进,它以简单的方式处理多个异步任务并让路。

这里有两个函数。两者都有效。 firstImage(inURLs:completion:) 只有 return 它下载成功的第一个 UIImageimages(forURLs:completion:) 尝试下载并 return 全部下载。

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: { [=11=] != nil }) ?? nil
}