我正在尝试获取用户的照片。在“朋友的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)
}
}
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填充阵列?我以为这是显而易见且简单的事情,但我无法理解此闭包有什么问题。
答案 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
}
})