我正在使用SwiftyVK和SwiftyJSON框架创建一个社交网络应用程序。有一个功能发送附有照片的帖子。我们称之为sendToVK()。以下是对它的简要回顾:
func sendToVK(message: String, photos: [UIImage]) {
// declaration of some vars and lets
var attachments = "" // this var should collect all the information about
//photos to attach, for example: "photo123456_987654,photo123456_612366,photo123456_123156",
// where 123456 is id of the user, whose wall I'm going post to (I already have it),
// numbers after "_" are id of the photo, they are contained in the server's response
// in case of successful upload
for photo in photos {
// I'm uploading photos in this loop, and I assume that I have to get
//the ID's of my photos from server's response also somewhere in this loop in order to work with them further
//Let's say photoString is someString + photoID, for example, photoString == "photo12345_9876543"
var photoID = ""
//the following function is uploading photos asynchronously.
//It is also responsible for getting IDs from server's response
VK.API.Upload.Photo.toWall.toUser(media, userId: userIDForVK).send(
onSuccess: { response in
print("\n SwiftyVK: uploadPhoto success \n \(response)")
photoID = response[0,"id"].stringValue }, //this is SwiftyJSON syntax
onError: { error in
print("\n SwiftyVK: uploadPhoto fail \n \(error)") },
onProgress: { done, total in
print("\n SwiftyVK: uploadPhoto progress: \(done) of \(total))") }
)
photoString = something + photoID //by this moment photoID is empty, that's the problem! (see explanation below)
attachments += photoString
}
//At this moment I must have all the neccessary parameters
//in the var wallPostParameters, including attachments!
VK.API.Wall.post(wallPostParameters).send(
onSuccess: {response in print(response)},
onError: {error in print(error)},
onProgress: {done, total in print(" !!!!!!!!!!!!!!! send \(done) of \(total)")}
)
}
所以确切的问题是,在循环内部,上传任务被分派到另一个线程,并且服务器的响应分别在另一个时间到达其他地方。事实上,到目前为止我需要附件字符串填充 photoString (在调用VK.API.Wall.post()之前),实际上有表格,例如“photo123456_,photo123456_,photo123456_”,即没有带照片的身份证,因为这些照片尚未在其他帖子中上传,因此这些ID未添加到附件。
问题是,如何在Swift中实现在循环的每次迭代中我们都没有继续但等到照片上传后,将其id添加到 photoString 以收集这些< 附件中的strong> photoString ,所以在调用VK.API.Wall.post()之前一切都准备好了吗?
答案 0 :(得分:0)
这样的事情可以适用于您的情况
func sendToVK(message: String, photos: [UIImage]) {
var attachments = ""
var photosUploaded = 0
for photo in photos {
var photoID = ""
VK.API.Upload.Photo.toWall.toUser(media, userId: userIDForVK).send(
onSuccess: { response in
photosUploaded += 1
photoID = response[0,"id"].stringValue
photoString = something + photoID
attachments += photoString
if photosUploaded == photos.count {
VK.API.Wall.post(wallPostParameters).send(
onSuccess: {response in print(response)},
onError: {error in print(error)},
onProgress: {done, total in print(" !!!!!!!!!!!!!!! send \(done) of \(total)")}
)
}
}, //this is SwiftyJSON syntax
onError: { error in
print("\n SwiftyVK: uploadPhoto fail \n \(error)") },
onProgress: { done, total in
print("\n SwiftyVK: uploadPhoto progress: \(done) of \(total))") }
)
}
}
答案 1 :(得分:0)
我在Swift上读过一篇关于GCD的文章,我的最终解决方案是:
private static func sendToVK(_ message: String, photos: [UIImage], userIDForVK: String) {
var wallPostParameters = Dictionary<VK.Arg, String>()
wallPostParameters[VK.Arg.message] = message
var attachments = ""
var successfulUploadsCount = 0
let sendPostWorkItem = DispatchWorkItem {
VK.API.Wall.post(wallPostParameters).send(
onSuccess: {response in print(response)},
onError: {error in print(error)},
onProgress: {done, total in print("\n send \(done) of \(total)\n")} )
}
for photo in photos {
let media = Media(imageData: Data(UIImageJPEGRepresentation(photo, 1.0)!), type: Media.ImageType.JPG)
VK.API.Upload.Photo.toWall.toUser(media, userId: userIDForVK).send(
onSuccess: { response in
let photoID = response[0,"id"].stringValue
let photoString = "photo" + userIDForVK + "_" + photoID
if attachments.isEmpty {
attachments = photoString
} else {
attachments += "," + photoString
}
successfulUploadsCount += 1
if successfulUploadsCount == photos.count {
wallPostParameters[VK.Arg.attachments] = attachments
sendPostWorkItem.perform()
}
print("\n SwiftyVK: uploadPhoto success \n \(response)\n") },
onError: { error in
print("\n SwiftyVK: uploadPhoto fail \n \(error)\n") },
onProgress: { done, total in
print("\n SwiftyVK: uploadPhoto progress: \(done) of \(total))\n") } )
}
if photos.isEmpty {
sendPostWorkItem.perform()
}
}