Swift Alamofire图像下载并分配给collectionView中的ImageView

Swift Alamofire图像下载并分配给collectionView中的ImageView,swift,Swift,我使用alamofire从api返回下载图像,api返回保存图像URL,我使用alamofire在for循环中从这些URL下载图像数据,但由于采用异步方法,数组中的图像没有顺序排列。此外,即使我使用主线程中的reloadData()将图像分配给collectionview,在视图初始化后我也看不到图像,但当我滚动collectionview时,图像会显示出来。我将图像存储在一个数组中 func fetchData(){ AF.request("https://api.rawg.

我使用alamofire从api返回下载图像,api返回保存图像URL,我使用alamofire在for循环中从这些URL下载图像数据,但由于采用异步方法,数组中的图像没有顺序排列。此外,即使我使用主线程中的reloadData()将图像分配给collectionview,在视图初始化后我也看不到图像,但当我滚动collectionview时,图像会显示出来。我将图像存储在一个数组中

func fetchData(){
    AF.request("https://api.rawg.io/api/games?key=ab904f882bf94fa9960857911498aa78", method: .get, parameters: nil, headers: nil, interceptor: nil).validate(statusCode: 200 ..< 299).responseJSON { AFdata in
                

                    do{
                        let game = try
                            JSONDecoder().decode(Game.self, from: AFdata.data!)
                    
                        self.games = game
                        
                        if let gameResults = self.games?.results{
                            
                            for gameItem in gameResults{
                                AF.request(gameItem.backgroundImage!, method: .get, parameters: nil, headers: nil, interceptor: nil).validate(statusCode: 200 ..< 299).responseData
                                    { AFdata in
                                        DispatchQueue.main.async {
                                             self.gameImages.append(UIImage(data: AFdata.data!)!)
                                        }
                                       
                                }
                                
                            }
                        }
                        
                        DispatchQueue.main.async {
                            self.gamesCollectionView.reloadData()
                        }
                    
                    }catch let jsonErr{
                        print(jsonErr)
                    }
            }
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: GameCollectionViewCell.identifier, for: indexPath) as! GameCollectionViewCell
    
    cell.backgroundColor = .blue
    cell.gameNameLabel.text = games?.results?[indexPath.item].name
    
    if(gameImages.count != games?.results?.count){
        cell.imageView.image = nil
    }else
    {
        cell.imageView.image = gameImages[indexPath.item]
    }
    
    return cell

}
func fetchData(){
AF.request(“https://api.rawg.io/api/games?key=ab904f882bf94fa9960857911498aa78,方法:.get,参数:nil,头:nil,拦截器:nil).validate(状态代码:200..<299).responseJSON{AFdata in
做{
让游戏=尝试
JSONDecoder().decode(Game.self,from:AFdata.data!)
self.games=游戏
如果让gameResults=self.games?.results{
用于gameResults中的gameItem{
请求(gameItem.backgroundImage!,方法:.get,参数:nil,头:nil,拦截器:nil)。验证(状态代码:200..<299)。响应数据
{AFdata in
DispatchQueue.main.async{
self.gameImages.append(UIImage(数据:AFdata.data!))
}
}
}
}
DispatchQueue.main.async{
self.gamesCollectionView.reloadData()
}
}接球手{
打印(JSONER)
}
}
}
func collectionView(collectionView:UICollectionView,cellForItemAt indexPath:indexPath)->UICollectionViewCell{
让cell=collectionView.dequeueReusableCell(带有ReuseIdentifier:GameCollectionViewCell.identifier,for:indexPath)作为!GameCollectionViewCell
cell.backgroundColor=.blue
cell.gamenamelab.text=games?.results?[indexath.item].name
if(gameImages.count!=游戏?.results?.count){
cell.imageView.image=nil
}否则
{
cell.imageView.image=gameImages[indexPath.item]
}
返回单元
}
}使用

这是演示

func fetchData(){
    AF.request("https://api.rawg.io/api/games?key=ab904f882bf94fa9960857911498aa78", method: .get, parameters: nil, headers: nil, interceptor: nil).validate(statusCode: 200 ..< 299).responseJSON { AFdata in
        
        
        do{
            let game = try
                JSONDecoder().decode(Game.self, from: AFdata.data!)
            
            self.games = game
            
            if let gameResults = self.games?.results{
                let dispatchGroup = DispatchGroup() //<--- Here
                
                for gameItem in gameResults{
                    AF.request(gameItem.backgroundImage!, method: .get, parameters: nil, headers: nil, interceptor: nil).validate(statusCode: 200 ..< 299).responseData
                    {
                        dispatchGroup.leave() //<--- Here
                        AFdata in
                        DispatchQueue.main.async {
                            self.gameImages.append(UIImage(data: AFdata.data!)!)
                        }
                        
                    }
                    
                }
            }
            dispatchGroup.notify(queue: .main) {
                self.gamesCollectionView.reloadData() //<--- Here
            }
            
            
        }catch let jsonErr{
            print(jsonErr)
        }
    }
}

func fetchData(){
AF.request(“https://api.rawg.io/api/games?key=ab904f882bf94fa9960857911498aa78,方法:.get,参数:nil,头:nil,拦截器:nil).validate(状态代码:200..<299).responseJSON{AFdata in
做{
让游戏=尝试
JSONDecoder().decode(Game.self,from:AFdata.data!)
self.games=游戏
如果让gameResults=self.games?.results{

让dispatchGroup=dispatchGroup()//您需要在游戏图像追加之前调用AF.request complition块内的reload collectionView函数。因为它需要时间获取数据,但您正在重新加载collectionView,然后再获取图像

func fetchData(){
AF.request("https://api.rawg.io/api/games?key=ab904f882bf94fa9960857911498aa78", method: .get, parameters: nil, headers: nil, interceptor: nil).validate(statusCode: 200 ..< 299).responseJSON { AFdata in
            

                do{
                    let game = try
                        JSONDecoder().decode(Game.self, from: AFdata.data!)
                
                    self.games = game
                    
                    if let gameResults = self.games?.results{
                        
                        for gameItem in gameResults{
                            AF.request(gameItem.backgroundImage!, method: .get, parameters: nil, headers: nil, interceptor: nil).validate(statusCode: 200 ..< 299).responseData
                                { AFdata in
                                    DispatchQueue.main.async {
                                         self.gameImages.append(UIImage(data: AFdata.data!)!)
                        self.gamesCollectionView.reloadData()

                                    }
                                   
                            }
                            
                        }
                    }
                
                }catch let jsonErr{
                    print(jsonErr)
                }
        }
func fetchData(){
AF.request(“https://api.rawg.io/api/games?key=ab904f882bf94fa9960857911498aa78,方法:.get,参数:nil,头:nil,拦截器:nil).validate(状态代码:200..<299).responseJSON{AFdata in
做{
让游戏=尝试
JSONDecoder().decode(Game.self,from:AFdata.data!)
self.games=游戏
如果让gameResults=self.games?.results{
用于gameResults中的gameItem{
请求(gameItem.backgroundImage!,方法:.get,参数:nil,头:nil,拦截器:nil)。验证(状态代码:200..<299)。响应数据
{AFdata in
DispatchQueue.main.async{
self.gameImages.append(UIImage(数据:AFdata.data!))
self.gamesCollectionView.reloadData()
}
}
}
}
}接球手{
打印(JSONER)
}
}

}

它可以工作,但图像的顺序与json中的顺序不一样,你知道有什么线索吗?因为图像的响应时间彼此不同。你可以使用递归函数来解决这个问题。在获取第一个图像之前,你不会获取其他图像,但这会导致很多性能问题。因此我建议使用翠鸟库获取单元格内的图像。这是从远程服务器将图像设置为imageview的正确方法。@AtakanKAlso如果可以解决您的问题,您可以将答案标记为正确吗?@Atakank答案是正确的,但我不能投票,因为我没有足够的声誉。您想在显示集合之前下载所有图像吗tionView?使用
Alamofire+Image
怎么样?这将让您在
UIImageView
上有一个方法来设置带有
URL
的图像:否则SDWebImage,翠鸟也会这样做。