I'm following a documentation on braintree for IOS.
It recommends to implement a method like this (in swift):
func onLookupComplete(_ request: BTThreeDSecureRequest, result: BTThreeDSecureLookup, next: @escaping () -> Void) {
// Optionally inspect the lookup result and prepare UI if a challenge is required
next()
}
My target code is some objective C for react native module where function are defined like this :
RCT_EXPORT_METHOD(getAddressLine1: (NSString *) address
callback: (RCTResponseSenderBlock) callback)
{ ... }
What would be the equivalent of the swift implementation for the objective C module (especially the "next: @escaping" part) ?
Note: here is the braintree doc
Thank you
CodePudding user response:
next: @escaping () -> Void
So () -> Void
, that's called a closure, and in Objective-C, it's called a Block.
@escaping
means that the method will "end" before the closure is called.
In other words, if you have func myMethod(escaped: @escaping () -> Void) -> Bool
, and if you write
let methodOutput = myMethod(escaped: {
print("here closure has been called")
}
print(methodOutput)
print(methodOutput)
has strong chances (but not necessarily) to be printed before print("here closure has been called")
. Usually because it's async.
Now, here's a sample from a UIView
method to know how to translate them:
In Swift:
class func animate(
withDuration duration: TimeInterval,
animations: @escaping () -> Void
)
In Objective-C:
(void)animateWithDuration:(NSTimeInterval)duration
animations:(void (^)(void))animations;
Now, I've said that it's not mandatory for it to be asynchronously called, because we could image this scenario in pseudo code:
func myMethod(escaped: @escaping () -> Void)) {
if canBeDone == false { //In Swift, a guard is better
escaped()
} else {
doLongAsyncProcess(onDidFinished: { escaped() })
}
}
If canBeDone
is false, the closure will be called directly (synchrone), but if not, it will be called later (asynchrone).