Swift 3: Transfer Utility enumerateToAssignBlocks

2019-04-25 07:13发布

Official AWS docs contains the following objective-c code

 AWSS3TransferUtility *transferUtility = [AWSS3TransferUtility defaultS3TransferUtility];
[transferUtility
 enumerateToAssignBlocksForUploadTask:^(AWSS3TransferUtilityUploadTask *uploadTask, __autoreleasing AWSS3TransferUtilityUploadProgressBlock *uploadProgressBlockReference, __autoreleasing AWSS3TransferUtilityUploadCompletionHandlerBlock *completionHandlerReference) {
     NSLog(@"%lu", (unsigned long)uploadTask.taskIdentifier);

     // Use `uploadTask.taskIdentifier` to determine what blocks to assign.

     *uploadProgressBlockReference = // Reassign your progress feedback block.
     *completionHandlerReference = // Reassign your completion handler.
 }
 downloadTask:^(AWSS3TransferUtilityDownloadTask *downloadTask, __autoreleasing AWSS3TransferUtilityDownloadProgressBlock *downloadProgressBlockReference, __autoreleasing AWSS3TransferUtilityDownloadCompletionHandlerBlock *completionHandlerReference) {
     NSLog(@"%lu", (unsigned long)downloadTask.taskIdentifier);

     // Use `downloadTask.taskIdentifier` to determine what blocks to assign.

     *downloadProgressBlockReference =  // Reassign your progress feedback block.
     *completionHandlerReference = // Reassign your completion handler.
 }];

I tried converting it into Swift 3 (upload task only)

transferUtility.enumerateToAssignBlocks(forUploadTask:
        {

            let progressPointer = AutoreleasingUnsafeMutablePointer<AWSS3TransferUtilityUploadProgressBlock?>(&uploadProgressBlock)
            let completionPointer = AutoreleasingUnsafeMutablePointer<AWSS3TransferUtilityUploadCompletionHandlerBlock?>(&completionBlock)

            progress = progressPointer
            completion = completionPointer

    }
        , downloadTask: nil)

But Xcode throws the following error

Cannot convert value of type ()->() to expected argument type[...]

Anyone got it working in Swift 3? Probably method signatures have changed

EDIT:

I applied @donkon answer:

        transferUtility.enumerateToAssignBlocks(forUploadTask: { (uploadTask:AWSS3TransferUtilityUploadTask, progress:AutoreleasingUnsafeMutablePointer<(@convention(block) (AWSS3TransferUtilityTask, Progress) -> Void)?>?, error: AutoreleasingUnsafeMutablePointer<(@convention(block) (AWSS3TransferUtilityUploadTask, Error?) -> Void)?>?) in

                        let progressPointer = AutoreleasingUnsafeMutablePointer<AWSS3TransferUtilityProgressBlock?>(&self.progressBlock)
                        let completionPointer = AutoreleasingUnsafeMutablePointer<AWSS3TransferUtilityUploadCompletionHandlerBlock?>(&self.completionHandler)
        //

                        progress = progressPointer

                        completion = completionPointer


    }, downloadTask: nil)

now Xcode tells that both progress and completion are let values and cannot be changed.

2条回答
女痞
2楼-- · 2019-04-25 07:34

The method you are trying to use has arguments that are functions. These functions in the SDK are written in Objective-C. So you should use @convention(block) to indicate that they are Objective-C compatible block references.

AWSS3TransferUtility.default().enumerateToAssignBlocks(forUploadTask: { (uploadTask:AWSS3TransferUtilityUploadTask, uploadProgressBlockReference:AutoreleasingUnsafeMutablePointer<(@convention(block) (AWSS3TransferUtilityTask, Progress) -> Void)?>?, completionHandlerReference: AutoreleasingUnsafeMutablePointer<(@convention(block) (AWSS3TransferUtilityUploadTask, Error?) -> Void)?>?) in
    print("Hello, world")

    uploadProgressBlockReference?.pointee = {(task:AWSS3TransferUtilityTask, progress:Progress) -> Void in
        print("Fraction completed:  \(progress.fractionCompleted)")
    }
}, downloadTask: nil)
查看更多
【Aperson】
3楼-- · 2019-04-25 07:54

It's not worth fighting that that method in swift, just go around it. I'm pretty sure this accomplishes the same thing doing this.

 func handleForeground() {
    if let multiPartUploadTasks = self.transferUtility.getMultiPartUploadTasks().result, let uploads = multiPartUploadTasks as? [AWSS3TransferUtilityMultiPartUploadTask] {
        for upload in uploads {
            upload.setProgressBlock(self.progressBlock)
            upload.setCompletionHandler(self.completionBlock)
        }
    }
}
查看更多
登录 后发表回答