Swift 3: Transfer Utility Enumeratetoassignblocks Method Signature

Swift 3: Transfer Utility enumerateToAssignBlocks method signature

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)

Why is my just created pointer throwing a KERN_INVALID_ADDRESS?

I don't think you should need most (or any) of these pointers. Take a look at the Swift example code from AWS and see if it doesn't do what you're looking for.

Creating pointers the way you have isn't safe in Swift. This is probably way more information than you need (you shouldn't have to work this hard), but here's what may be happening (this explanation doesn't feel completely right in this case, but it's something that can happen, so it's worth knowing about):

  • You create a pointer to a local (stack) variable, progressBlock.
  • The system sees that progressBlock is no longer accessed anywhere else in scope.
  • As it's allowed to do, ARC destroys progressBlock.
  • You unsafely access the pointer to the destroyed variable, and crash.

I say this doesn't feel right, because there's a second reference to the closure that should keep the closure alive anyway, but as a rule, creating pointers with a constructor this way is very dangerous.

(It's possible this crashes because you can't print a @convention(block) closure; I've never tried to do that. It's not a very normal thing to try to print.)

In any case, if you really did need to do this kind of thing (and I think you don't), you'd need to do it along these lines:

withUnsafeMutablePointer(to: self.uploadProgressHandler) { newProgressPointer in 
... newProgressPointer is safe to use in this block ...
}

But as a rule, if you're converting ObjC code (not pure C, but just ObjC), and find you're having to create a lot of Unsafe objects, you may be walking down the wrong path. Most ObjC things bridge to Swift fine w/o Unsafe.

CompletionHandler Swift 3

Check the signature of the AWSS3TransferUtilityUploadCompletionHandlerBlock, now Swift 3 doesn't allow auto type-casting. Swift 3 doesn't allow you to define the completionBlock with different signature, check the ? and ! as well.

What is the Swift 3 syntax for creating an AWSTask with a result?

Simply add as NSArray like this:

let results = ["resultOne", "resultTwo"] as NSArray
let task = AWSTask(result: results)

Because results must confirm to Protocol AnyObject when define AWSTask:

open class AWSTask<ResultType : AnyObject> : NSObject {...}

In swift 2.2 ["resultOne", "resultTwo"] is auto brige to NSArray,

But in swift 3.0 you have to brige [String] to NSArray manually.

This is the explanation:

https://github.com/apple/swift-evolution/blob/master/proposals/0072-eliminate-implicit-bridging-conversions.md

AWSS3TransferUtility: How to retry failed upload task after app restart

By default, the retry limit seems to be 0. It can be changed by setting

AWSS3TransferUtilityConfiguration().retryLimit = ...

resume() is not applicable in this case.

How to specify the range 'in:' argument of Swift 3 method range(of:options:in)

To create a Range<Data.Index> literally you have to use the CountableRange operator and annotate the type:

let data = Data(0..<100)
let subData = Data(0..<2)

let myrange : Range<Data.Index> = 0..<4
let rang = data.range(of: subData, in: myrange) // Range(0..<2)

Foundation NSRange and Swift Range are two completely different things.

By the way: The options parameter has a default value of no options and can be omitted.

StringByAppendingPathComponent() and WriteToFile()

Regarding the first part of your question, as dan stated in the comments you should be using fullPath.appendingPathComponent(name) instead.

Regarding your second question:

The main difference between writeToFile and write(to: is the fact that the first is for Strings and the seconds is for NSData.

Somewhat related:

According to the NSData Class Reference

In iOS 2.0+ you have:

write(to:atomically:)

and

write(toFile:atomically:)

Given:

Since at present only file:// URLs are supported, there is no
difference between this method and writeToFile:atomically:, except for
the type of the first argument.

None of this has changed in Swift 3 according to the Swift Changelog.

Fetch only Live Photos using Photos Framework dosen't work

You can't supply a Swift enumeration value to that method - it needs a long (as is implied by the %ld format string), so use

fetchOptions.predicate = NSPredicate(format: "mediaSubtype == %ld", PHAssetMediaSubtype.PhotoLive.rawValue)

to access the underlying integer value of the enumeration value



Related Topics



Leave a reply



Submit