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 String
s 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
Apn Custom Notification Sound Issue
Custom Uibarbuttonitem with Bg Colour and Text Swift 3
How to Install Self-Signed Certificates in iOS 11
How to Make a Reusable Tableview for Different Screens in the Same Application
iOS - Emphasise with Bold Strings in Localizable.Strings
iOS: Is Possible to Rounder Radius with Different Value in Each Corner
Why [Uiscreen Mainscreen].Bounds] Is Not Returning Full Screen Size
Track Touch Points in Multitouch
Fixing Low Fps in Swift Playground
Fetch() Doing Get Instead of Post on React-Native (iOS)
Will Download Resume After Closing My App in Background Mode
How to Connect Xcode 9 and Github
Invalid Transaction Receipt Returned by Appstorereceipturl (Nsdata), in iOS 7
I Get Nil When Using Nsdateformatter in Swift