Alamofire不会在响应关闭中执行整个代码

时间:2020-06-27 08:04:35

标签: ios swift

我正在尝试获取用户的照片。在“朋友的T​​ableView”列表上,我调用该函数

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard segue.identifier == "showFriendSegue" else {return}
        guard let showFriend = segue.destination as? FriendCollectionViewController else {return}
        let indexPath = self.tableView.indexPathForSelectedRow
        let userKey = usersSectionTitles[indexPath!.section]
        if let userValues = usersDictionary[userKey] {
            let user = userValues[indexPath!.row]
            let id  = userValues[indexPath!.row].id
            showFriend.friend.append(user)
            showFriend.friendImages = Photo.photo.getUserPhotos(id: id)
        }
    }
func getUserPhotos(id: Int) -> [String]{
        let url = URL(string: "https://api.vk.com/method/photos.get")!
        let parameters: Parameters = [
            "owner_id" : id,
            "album_id" : "profile",
            "rev" : 1,
            "access_token" : Session.session.token,
            "v": Session.session.APIVersion
        ]
        
        var userPhotos: [String] = []
    
        AF.request(url, method: .get, parameters: parameters, headers: nil).responseJSON { (response) in
            switch response.result {
            case .success(let value):
                let json = JSON(value)
              
                let photosArray = json["response"]["items"].arrayValue

                for sizes in photosArray {
                    let onlyOneType = sizes["sizes"].arrayValue.filter({$0["type"] == "z"})
                    for url in onlyOneType {
                        userPhotos.append(url["url"].stringValue)
                    }
                }

            case .failure(let error):
                print(error)
            }
        }
        return userPhotos
    }

在我看来,Alamofire似乎没有足够的时间来编写完整的代码,这很奇怪,因为我希望代码可以一致地执行。 当我检查带有断点的代码时,我看到AF.request启动,然后立即执行了userPhotos返回,photosArray不是空的,但是在朋友的页面上我有一个空的照片数组。 如何从AF填充阵列?我以为这是显而易见且简单的事情,但我无法理解此闭包有什么问题。

1 个答案:

答案 0 :(得分:2)

Alamofire请求异步运行,这就是为什么您的代码一次返回空userPhotos的原因。您需要为此功能使用完成处理程序。当您的请求返回带有ID的响应时,它将被调用。

我建议在FriendCollectionViewController中而不是func prepare(for segue: UIStoryboardSegue, sender: Any?)中调用此函数。

在下面的示例中附加代码段。

func getUserPhotos(id: Int, completion: @escaping (Result<[String], Error>) -> Void) {
        let url = URL(string: "https://api.vk.com/method/photos.get")!
        let parameters: Parameters = [
            "owner_id" : id,
            "album_id" : "profile",
            "rev" : 1,
            "access_token" : Session.session.token,
            "v": Session.session.APIVersion
        ]
        AF.request(url, method: .get, parameters: parameters, headers: nil).responseJSON { (response) in
            switch response.result {
            case .success(let value):
                let json = JSON(value)
              
                let photosArray = json["response"]["items"].arrayValue
                var userPhotos: [String] = []
                for sizes in photosArray {
                    let onlyOneType = sizes["sizes"].arrayValue.filter({$0["type"] == "z"})
                    for url in onlyOneType {
                        userPhotos.append(url["url"].stringValue)
                    }
                }
                completion(.success(userPhotos))

            case .failure(let error):
                print(error)
                completion(.failure(error))
            }
        }
    }

然后您可以调用您的方法。

Photo.photo.getUserPhotos(id: friend[0].id, completion: { result in
    switch result {
    case .success(let ids):
      // handle your ids here
    case .failure:(let error):
      // handle error
    }
})