In this line, the error was Display. Can someone tell me what mistake was made?
Stripe.createTokenWithCard(card, completion: { (token: STPToken!, error: NSError!) -> Void in
self.handleToken(token)
I had the same problem after updating Stripe in pods recently. That method is deprecated. Instead, you can use the following code:
STPAPIClient.sharedClient().createTokenWithCard(card, completion: { (token: STPToken!, error: NSError!) -> Void in
})
It takes the same parameters.
Update
Thanks to #Christine and #Keyhole150
This function in Stripe API has now be changed to
STPAPIClient.sharedClient().createTokenWithCard(card, completion: { (token: STPToken?, error: NSError?) -> Void in
})
Thanks, #Shali! Your tip is helpful.
For those who are beginners like me, you might still get an error. In case you experience an error indicating either an extra argument in call before adding sharedClient() or how createTokenWithCard cannot be invoked after sharedClient() is added, it helps to make the completion arguments optional (as in STPToken? and NSError?).
As mentioned by Christine, the method now uses Optionals so it looks like the following:
STPAPIClient.sharedClient().createTokenWithCard(card, completion: { (token: STPToken?, error: NSError?) -> Void in
})
For objective-c using latest stripe pod
#import "Stripe.h"
STPCardParams *cardParams = [[STPCardParams alloc] init];
cardParams.number = #"4242424242424242";
cardParams.expMonth = 10;
cardParams.expYear = 2018;
cardParams.cvc = #"123";
[[STPAPIClient sharedClient] createTokenWithCard:cardParams completion:^(STPToken *token, NSError *error) {
if (token == nil || error != nil) {
// Present error to user...
NSLog(#"%#",error.description);
return;
}
NSLog(#"token.tokenId :: %#",token.tokenId);
}];
Related
I have a SDK integration that returns a response using a completion but I want to create another completion to return the callback response, but I don't know how.
This is my attempt to do that
func validatingProcces(completion: ((Any)?)->()) {
let conekta = Conekta()
conekta.delegate = self
conekta.publicKey = "key_KJysdbf6PotS2ut2"
conekta.collectDevice()
let card = conekta.card()
let token = conekta.token()
card!.setNumber(String(cardToSave!.cardNumber), name: cardToSave!.fullName, cvc: String(cardToSave!.cvc), expMonth: String(cardToSave!.month), expYear: String(cardToSave!.year))
token!.card = card
token!.create(success: { (data) -> Void in
completion(data as Any)
}, andError: { (error) -> Void in
print(error as Any)
completion(error as Any)
})
}
I have the following error:
Escaping closure captures non-escaping parameter 'completion'
and also:
Parameter 'completion' is implicitly non-escaping
Captured here
Ps. You'll find the SDK integration here:
https://github.com/conekta/conekta-ios
Thank you so much!
From the source code it looks like you could just make a callback like this:
completion: #escaping (Any?, Error?) -> ()
and pass in the result of the api callback so you can handle it elsewhere like this
token!.create(success: { data in
completion(data, nil)
}, andError: { error in
print(error as Any)
completion(nil, error)
})
Let me know if this works
I have optionals (NSError?) that are flagged by Xcode/Swift as non-escaping. These are called within a function (that has #escaping on its closure) by a second function (also with #escaping on its closure). The problem seems to be that the errors are not captured in the closure of either function and so Xcode/Swift is seeing them as potentially escaping.
Previous stack overflow posts had noted 'withoutActuallyEscaping' as a workaround. That no longer seems to be supported (Xcode version 8.2.1).
Refactoring to try to keep everything local to the function has not worked. I've also tried moving all of the NSError? to Error (via local enum), but that also hasn't worked.
The core problem is how to enable an error returned (via success/failure) from one function to the calling statement to be either captured locally and retained or tagged as escaping so that Swift/XCode can compile.
Again, this was working in Swift 2.3, so I'm looking for suggestions on how to refactor or what to look at for correctly handling these calls with NSError or Error.
This is part of a large code stack (about 25K lines). I'm posting part of the stack below (given Hamish's comment) to try and make the question clearer. Currently there are about 17-different variations of this error that are present in the code-stack.
public func fetchMostRecentSamples(ofTypes types: [HKSampleType], completion: #escaping HMTypedSampleBlock)
{
let group = DispatchGroup()
var samples = [HKSampleType: [MCSample]]()
let updateSamples : ((MCSampleArray, CacheExpiry) -> Void, (MCError) -> Void, HKSampleType, [MCSample], MCError) -> Void = {
(success, failure, type, statistics, error) in
guard error == nil else {
failure(error)
return
}
guard statistics.isEmpty == false else {
failure(error)
return
}
samples[type] = statistics
success(MCSampleArray(samples: statistics), .never)
}
let onStatistic : ((MCSampleArray, CacheExpiry) -> Void, (MCError) -> Void, HKSampleType) -> Void = { (success, failure, type) in
self.fetchMostRecentSample(type) { (samples, error) in
guard error == nil else {
failure(error)
return
}
Then fetchMostRecentSample has this header:
public func fetchMostRecentSample(_ sampleType: HKSampleType, completion: #escaping HMSampleBlock)
and the error message on the failure is "Closure use of non-escaping parameter 'failure' may allow it to escape" : "Parameter 'failure' is implicitly non-escaping"
Note that the let updateSamples is fine (not calling another function), but that the onStatistic with the failure (having error codes) is where the problem with escaping/non-escaping is coming from. MCError is an enum with the error codes (refactored from NSError? in Swift 2.3 version).
Major credits to Hamish for helping me to see into this. In case it helps others coming across this on their Swift 3 conversions, the other place that I stumbled was in assuming that all of our third-party pods were complete if they stated ready for Swift 3. In this case I had to update the AwesomeCache code to handle the errors correctly:
open func setObject(forKey key: String, cacheBlock: #escaping (#escaping(CacheBlockClosure), #escaping(ErrorClosure)) -> Void, completion: #escaping (T?, Bool, NSError?) -> Void) {
if let object = object(forKey: key) {
completion(object, true, nil)
} else {
let successBlock: CacheBlockClosure = { (obj, expires) in
self.setObject(obj, forKey: key, expires: expires)
completion(obj, false, nil)
}
let failureBlock: ErrorClosure = { (error) in
completion(nil, false, error)
}
cacheBlock(successBlock, failureBlock)
}
}
This is simply adding two more #escaping beyond what was in the github master. Otherwise, as Hamish pointed out, it comes down to paying attention to where #escaping needs to be added on the function calls. The update for AwesomeCache came from code like this:
aggregateCache.setObjectForKey(key, cacheBlock: { success, failure in
let doCache : ([MCAggregateSample], NSError?) -> Void = { (aggregates, error) in
guard error == nil else {
failure(error)
return
}
success(MCAggregateArray(aggregates: aggregates), .Date(self.getCacheExpiry(period)))
}
where the success, failure will be flagged as potentially escaping without the code changes on the AwesomeCache.
I am New for Swift and I Have Implement File Manager Concept in my Project but it shows the issue and I don't for how to solve this please any body help me for fix the issue.
Here I Post My Code.
class func addSkipBackupAttributeToItemAtPath(filePathString: String) throws -> Bool
{
let URL: NSURL = NSURL.fileURLWithPath(filePathString)
assert(NSFileManager.defaultManager().fileExistsAtPath(URL.path!))
let err: NSError? = nil
let success: Bool = try URL.setResourceValue(Int(true), forKey: NSURLIsExcludedFromBackupKey) //---- This Line Shows the Issue.
if !success {
NSLog("Error excluding %# from backup %#", URL.lastPathComponent!, err!)
}
return success
}
The benefit of the new error handling in Swift 2 is the omission of the quasi-redundant return values Bool / NSError. Therefore setResourceValue does not return a Bool anymore which is the reason of the error message.
As the function is marked as throws I recommend this syntax which just passes the result of setResourceValue
class func addSkipBackupAttributeToItemAtPath(filePathString: String) throws
{
let url = NSURL.fileURLWithPath(filePathString)
assert(NSFileManager.defaultManager().fileExistsAtPath(URL.path!))
try url.setResourceValue(true, forKey: NSURLIsExcludedFromBackupKey)
}
Handle the error in the method which calls addSkipBackupAttributeToItemAtPath
The method setResourceValue is a throw function and does not return a Bool.
Try running your function using a do-catch:
do {
try URL.setResourceValue(Int(true), forKey: NSURLIsExcludedFromBackupKey)
}
catch {
NSLog("Error excluding %# from backup %#", URL.lastPathComponent!, err!)
}
I updated Xcode to 6.3, and found there’s some new error in my codes with new Swift 1.2.
user.signUpInBackgroundWithBlock {
(success:Bool!, error:NSError!) -> Void in
if !(error != nil) {
println("sign up successfully")
var loginAlert: UIAlertController = UIAlertController(title: "Sign Up", message: "Sign Up Succeeded", preferredStyle: UIAlertControllerStyle.Alert)
self.presentViewController(loginAlert, animated: true, completion: nil)
loginAlert.addAction(UIAlertAction(title: "Okay", style:
I got this error:
Cannot invoke signUpInBackgroundWithBlock with an argument list of type ((Bool!, NSError!) -> void)
How can I fix it?
Another one
#IBAction func endend(sender: AnyObject) {
if (PFUser.currentUser() == nil) {
PFUser.logInWithUsernameInBackground(usernameTextField.text, password: passwordTextField.text){
(user:PFUser!, error:NSError!) -> Void in
if user != nil {
println("login chenggong")
var tlvc = TimelineViewControllerTableViewController()
self.presentViewController(tlvc, animated: true, completion: nil)
}
else {
println("failed")
}
}
}
}
I got this error :
“UITextField” does not have member named “text”.
And I got 3 errors that about }, it says
Expected “,” separator.
Expected expression in list of expressions.
Expected “)” in expressions.
I can ran my app before Swift 1.2, but now...
Following code worked for me:
PFUser.logInWithUsernameInBackground(username.text as String!, password: password.text as String!){
(loggedInuser: PFUser?, signupError: NSError?) -> Void in
In Xcode, go to Edit > Convert... > To Latest Swift Syntax...
There are several language syntax changes in the new release, so Apple included a tool to help migrate older Swift code. From what I've been reading it's largely useful but doesn't always solve 100% of the problems. Hopefully it'll at least reduce the number of errors you're seeing.
For Parse sign up blocks, the Swift 1.2 compiler does not like it when you force unwrap the boolean success parameter.
Removing the '!' after 'success:Bool' should remove the errors you are getting.
Try changing:
user.signUpInBackgroundWithBlock{(success:Bool!, error:NSError!) -> Void in
To:
user.signUpInBackgroundWithBlock{(success:Bool, error:NSError!) -> Void in
Try changing:
user.signUpInBackgroundWithBlock{(success:Bool!, error:NSError!) -> Void in
To:
user.signUpInBackgroundWithBlock{(success:Bool?, error:NSError?) -> Void in
FBRequestConnection.startForPostOpenGraphObject(graphObject, {connection, result, error in
if(!error) {
var objectID : NSString = result.objectforKey("id")
println(objectID)
} else {
println(error.description)
}
})
I'm getting the following error on the expression:
Cannot convert the expression's type 'FBRequestConnection!' to 'Void'
I have looked all over SO but couldn't find a solution. Any ideas?
Help would be much appreciated. Thanks.
Maybe check your handler syntax. It should be something like:
let handler:FBRequestHandler = { (connection : FBRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
if (error != nil) {
println(error)
} else {
println(result)
}
}
Myself, I'm struggling with getting FBOpenGraphObject from FBGraphObject.openGraphObjectForPost()