Ios 阿拉莫菲尔不';t在响应闭包中执行整个代码

Ios 阿拉莫菲尔不';t在响应闭包中执行整个代码,ios,swift,Ios,Swift,我正在尝试获取用户的照片。在朋友列表的TableView中,我调用该函数 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard segue.identifier == "showFriendSegue" else {return} guard let showFriend = segue.destination as? FriendCollection

我正在尝试获取用户的照片。在朋友列表的TableView中,我调用该函数

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)
        }
    }
对我来说,Alamofire似乎没有足够的时间来编写整个代码,这很奇怪,因为我希望代码应该一致地执行。 当我用断点检查代码时,我看到AF.request启动,然后立即返回userPhotos执行,photosArray不是空的,但是在朋友的页面上,我有一个空的照片数组。
如何从AF填充数组?我认为这是显而易见且简单的事情,但我不明白这个闭包有什么错。

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

我建议在
FriendCollectionViewController
中调用此函数,而不是
func prepare(对于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))
            }
        }
    }

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

我建议在
FriendCollectionViewController
中调用此函数,而不是
func prepare(对于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))
            }
        }
    }

谢谢!但是我该怎么称呼这个呢?现在函数请求完成字段,我必须在那里写什么?我正在尝试friendImages=Photo.Photo.getUserPhotos(id:friend[0].id)很抱歉打扰您,但我想我很笨。在FriendController上,我有一个空数组:FriendPhotos。在DidLoad中调用我的方法,在block.success中调用FriendsPhotos=ids。然后再次在DidLoad中,我用“if…”检查数组是否为空。但当我点击我的朋友时,该检查显示我的数组为空,然后才阻塞。成功执行您可以共享视图控制器的代码,以查看流中的错误。如果在调用方法获取标识符后,在下一行尝试检查数组是否为空,则该数组始终为空,因为请求需要一些时间才能获得响应,这就是为什么在等待API响应时异步调用该数组以防止阻塞用户体验。override func viewDidLoad(){super.viewDidLoad()Photo.Photo.getUserPhotos(id:friend[0]。id,完成:{切换结果中的结果{case.success(let-id):self.friendImages=ids case.failure(let-error):print(error)}如果friendImages.isEmpty{friendImages=[“nameOfImageThatIsShown=friendImages[0]}其他{nameOfImageThatIsShown=friendImages[0]}quantityOfUserImages=friendImages.countIt看起来很糟糕。我是第一次来这里,如何才能让我的代码更具可读性?非常感谢!但我应该如何调用它?现在函数requars completion字段,我必须在那里写些什么?我正在尝试friendImages=Photo.Photo.getUserPhotos(id:friend[0].id)抱歉打扰了,但我想我很笨。在FriendController上,我有一个空数组:FriendPhotos。在DidLoad中,我调用我的方法并在block中。成功时,我说FriendsPhotos=ids。然后在DidLoad中,我再次用“if…”检查我的数组是否为空。但是,当我点击我的朋友时,此检查显示我的数组为空,然后才阻止。成功执行。您可以共享视图控制器的代码,以查看流中的错误。如果在调用方法获取标识符后,尝试在下一行检查数组是否为空,则该数组始终为空,因为您的请求需要一些时间来验证这就是为什么在等待API响应时异步调用它以防止阻塞用户体验。重写func viewDidLoad(){super.viewDidLoad()Photo.Photo.getUserPhotos(id:friend[0]。id,completion:{result in switch result{case.success(let-ids):self.friendImages=ids case.failure(let error):print(error)})if-friendImages.isEmpty{friendImages=[“nameofimagethatShown=friendImages[0]}else{nameofimagethatShown=friendImages[0]}quantityOfUserImages=friendImages.countIt看起来糟透了。我是第一次来这里,如何才能让我的代码更具可读性?
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
    }
})