Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/101.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift:如何从异步操作返回值?_Ios_Multithreading_Swift3_Vk - Fatal编程技术网

Ios Swift:如何从异步操作返回值?

Ios Swift:如何从异步操作返回值?,ios,multithreading,swift3,vk,Ios,Multithreading,Swift3,Vk,我正在使用SwiftyVK和SwiftyJSON框架创建一个社交网络应用程序。有一个功能,它发送一个附带照片的帖子。让我们称之为sendToVK()。以下是对它的简要回顾: func sendToVK(message: String, photos: [UIImage]) { // declaration of some vars and lets var attachments = "" // this var should collect all the informatio

我正在使用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)")}
        )
}
因此,确切的问题是,在循环内部,上载任务被分派到另一个线程,服务器的响应在另一个时间分别到达其他地方。事实上,当我需要我的附件字符串填充photoStrings时(就在调用VK.API.Wall.post()之前),它实际上有一个表单,例如,“photo123456,photo123456,photo123456”,即没有照片ID,因为这些照片还没有上传到另一个线程中,因此,这些ID没有添加到附件中


问题是,我如何在Swift中实现,在循环的每个迭代中,我们不继续,而是等待照片上传,将其id添加到photoString以收集附件中的photoString,所以在调用VK.API.Wall.post()之前一切都准备好了吗?

像这样的东西在你的情况下会有用的

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))") }
       )

    }


}

我在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()
        }
    }
private static func sendToVK(umessage:String,photos:[UIImage],userIDForVK:String){
var wallPostParameters=字典()
wallPostParameters[VK.Arg.message]=消息
var attachments=“”
var successfulluploadsCount=0
让sendPostWorkItem=DispatchWorkItem{
VK.API.Wall.post(wallPostParameters.send)(
onSuccess:{打印响应(响应)},
OneError:{打印错误(错误)},
onProgress:{完成,打印总数(“\n发送\(完成)\(总计)\n”)})
}
对于照片中的照片{
让媒体=媒体(imageData:Data(UIImageJPEGresentation(photo,1.0)!),类型:media.ImageType.JPG)
API.Upload.Photo.toWall.toUser(媒体,用户名:userIDForVK).send(
onSuccess:{中的响应
让photoID=response[0,“id”].stringValue
让photoString=“photo”+userIDForVK+“\u”+photoID
如果附件是空的{
附件=photoString
}否则{
附件+=”,“+photoString
}
成功上载NT+=1
如果成功上载,则NT==photos.count{
wallPostParameters[VK.Arg.attachments]=附件
sendPostWorkItem.perform()
}
打印(“\n SwiftyVK:uploadPhoto success\n\(response)\n”),
onError:{中有错误
打印(“\n SwiftyVK:uploadPhoto失败\n\(错误)\n”),
onProgress:{已完成,总计
打印(“\n SwiftyVK:uploadPhoto progress:\(完成)共\(总计))\n”)})
}
如果照片是空的{
sendPostWorkItem.perform()
}
}

如果你有要上传的照片数量,只需在循环之外再做一个变量,在每次成功时+1,并将其与要上传的照片数量进行比较,然后只执行代码,代码也应该放在闭包调用中back@Tj3n我怎样才能防止以下代码在Swift中执行?下面的答案看起来不错:D