I have a project that I am converting to swift 3. In my printing code, which has been working in swift 2.3 and iOS 9, I have the following lines:
func completionFunc(_: UIPrintInteractionController, _: Bool, _: NSError? ){
// some action
}
DispatchQueue.main.async{
printController.present( animated: true, completionHandler: completionFunc )
}
now I am getting the following error:
error: cannot convert value of type '(UIPrintInteractionController, Bool, NSError?) -> ()' to expected argument type 'UIPrintInteractionCompletionHandler?'
printController.present( animated: true, completionHandler: completionFunc )
^~~~~~~~~~~~~~
From the documentation the definition of UIPrintInteractionCompletionHandler is:
typealias UIPrintInteractionCompletionHandler = (UIPrintInteractionController, Bool, Error?) -> Void
so I can not understand the error that has just appeared when trying to migrate the code to swift 3.
Thanks
Reza
Related
I'm using the swift package OnboardKit and it requires a specific closure type that I cannot figure out.
The class OnboardPage requires a type OnboardPageAction for the parameter action.
public typealias OnboardPageCompletion = ((_ success: Bool, _ error: Error?) -> Void)
public typealias OnboardPageAction = (#escaping OnboardPageCompletion) -> Void
OnboardPage(title: "Title",
description: "description",
action: action)
This is my latest attempt, I tried several variations along those lines.
let action: ((_ success: Bool, _ error: Error?) -> ()) = {_,_ in
print("help")
}
XCode fails with the error message:
Cannot convert value of type '(Bool, Error?) -> Void' to expected
argument type 'OnboardPageAction?' (aka 'Optional<(#escaping (Bool,
Optional) -> ()) -> ()>')
What am I doing wrong here? Is the mistake in my closure definition or in the way I use it in the OnboardPage() call? Thanks :)
(I learned details about closures here Closures Swift How To, but I am not able to define the right closure type that the package expects)
Judging from the context, I guess that the purpose of the action parameter is to allow you run some code when an OnboardPage is presented. This "action" might take some time (it might not finish when action returns), so it gives you a completion handler parameter that you can call to indicate that what you want to do is done.
If you just want to print Hello, you can just call the parameter after you printed hello to indicate that you finished what you want to do:
OnboardPage(title: "Title",
description: "description",
action: { completion in
print("Hello")
completion(true, nil)
})
or simply
OnboardPage(title: "Title",
description: "description") {
print("Hello")
$0(true, nil)
}
The first argument indicates whether the action is successful, the second contains an optional error for when it fails.
The declaration of an action should look like this to match the defintions provided:
let action: OnboardPageAction = { (_ closure: ((_ success: Bool, _ error: Error?) -> Void)) in
print("action")
}
After I update Xcode Version 8.0 (8A218a) swift 3, I got this error
Cannot assign value of type '(String?, Bool, [AnyObject]?, NSError?) -> ()' to type 'UIActivityViewControllerCompletionWithItemsHandler?'
activityview.completionWithItemsHandler = {(activityType: String?, completed:Bool, returnedItems:[AnyObject]?, error: NSError?) in
if !completed {
print("cancelled")
return
}else{
complele()
}
}
I have been following this Cannot assign a value of type '(String!, Bool, [AnyObject]!, NSError!)->Void to a value of type UIActivityViewControllerCompletionWithItemsHandler?'
But i still got the error message.
It works well in previous version 7.3.1 swift 2.
Use UIActivityType instead of String, [Any] instead of [AnyObject] and Error instead of NSError like this.
activityview.completionWithItemsHandler = {(activityType: UIActivityType?, completed:Bool, returnedItems:[Any]?, error: Error?) in
if !completed {
print("cancelled")
return
}else{
complele()
}
}
Check apple documentation for more detail.
What could be wrong with this line in Swift 3 that causes trying to build the app to fail...
storeViewController.loadProduct(withParameters: productparameters, completionBlock: { (success: Bool, error: NSError?) -> Void in
})
I am not getting an error shown on that line. I am getting the "Command failed due to signal: Segmentation fault: 11" error. Within that error's log it points me to the line:
2. While type-checking expression at [/Users/MyApp/MyViewController.swift:327:13 - line:331:14] RangeText="storeViewController.loadProduct(withParameters: productparameters, completionBlock: { (success: Bool, error: NSError?) -> Void in
})"
If I comment that line out, the app builds and runs without problem.
The lines that come before it:
let storeViewController:SKStoreProductViewController = SKStoreProductViewController();
storeViewController.modalPresentationStyle = .pageSheet
storeViewController.delegate = self;
self.present(storeViewController, animated: true, completion: nil);
let productparameters = [SKStoreProductParameterITunesItemIdentifier:idString, SKStoreProductParameterAffiliateToken:affString, SKStoreProductParameterCampaignToken:campString];
Replacing NSError with Error was the solution for me at this time.
storeViewController.loadProduct(withParameters: productparameters, completionBlock: { (success: Bool, error: Error?) -> Void in
})
I am using Parse and I have a signup page where I call:
user.signUpInBackgroundWithBlock { (succeeded: Bool, error: NSError?) -> Void in
I checked and this works on previous versions of Xcode, however there was a similar problem when Swift 1.2 came out, though it doesn't solve my problem.
The error I get is:
Cannot invoke 'signupInBackgroundWithBlock' with an argument list of type: '((Bool, NSError?) -> Void )'
I'd be grateful for any help.
You should change the type of succeeded value to ObjCBool. The signature of PFBooleanResultBlock now changed (Bool, NSError?) -> Void to (ObjCBool, NSError?) -> Void
So you should change the type Bool to ObjCBool, like below:
user.signUpInBackgroundWithBlock { (succeeded: ObjCBool, error: NSError?) -> Void in
print(succeeded)
print(error)
}
or just remove the type to make the compiler inferring the type.
user.signUpInBackgroundWithBlock { (succeeded, error) -> Void in
print(succeeded)
print(error)
}
I'm trying to utilize swift's SKStoreProductViewController, but am getting errors with my syntax, specifically with my completion block.
Here is my code:
let storeViewController:SKStoreProductViewController = SKStoreProductViewController();
storeViewController.delegate = self;
var productparameters = [SKStoreProductParameterITunesItemIdentifier:someitunesid];
storeViewController.loadProductWithParameters(productparameters,
(success: Bool!, error: NSError!) -> Void in
if success {
self.presentViewController(storeViewController, animated: true, completion: nil);
} else {
NSLog("%#", error)
}
)
After running this I get an expected "," separator error between the error:NSError!),-> Void
This doesn't make sense to me as the apple docs call for:
func loadProductWithParameters(_ parameters: [NSObject : AnyObject]!,
completionBlock block: ((Bool, NSError!) -> Void)!)
What am I doing wrong?
You're 99% there, you just need braces around your block to have the correct closure syntax:
storeViewController.loadProductWithParameters(productparameters, { (success: Bool!, error: NSError!) -> Void in
if success {
self.presentViewController(storeViewController, animated: true, completion: nil);
} else {
NSLog("%#", error)
}
})
You can read more about closures in Apple's documentation.