Cannot convert value of type 'Timer' to expected argument type '(() -> Void)?' Swift 5 - swift5

I am facing an issue while adding Timer inside the completion block of the present alert controller.
Error: Cannot convert value of type 'Timer' to expected argument type '(() -> Void)?'
func showAutoHideAlert() {
let alertController = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
present(alertController, animated: true, completion: Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false) { _ in
self.dismiss(animated: true, completion: nil)
})
}
Please help how to resolve this issue. Thanks

Related

Pass "function with parameter" as parameter

This doesn't compile
func showAlert(_ title: String, message: String,
onOk: (()->())? = nil,
onAnotherAction:((anotherActionTitle : String)-> Void)? = nil) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default) { (action) in
onOk?()
}
let anotherAction = UIAlertAction(title: anotherActionTitle, style: .default) { (action) in
onAnotherAction?()
}
alertController.addAction(ok)
alertController.addAction(anotherAction)
...
}
This compiles
func showAlert(_ title: String, message: String,
onOk: (()->())? = nil,
onAnotherAction:((String)-> Void)? = nil)
However, I have to declare another parameter for the title anotherActionTitle of onAnotherAction().
Is there a way make the first approach work? Thanks!
However, I have to declare another parameter for the title anotherActionTitle of onAnotherAction()
No, you don't have to do that. Just make it a normal parameter of the function as a whole:
func showAlert(_ title: String, message: String,
onOk: (()->())? = nil,
anotherActionTitle: String? = nil,
onAnotherAction: (()->())? = nil) {
The rest of your function will then compile and work correctly.
Since the implementation of SE-0111 as part of Swift 3, it is no longer possible to have named parameters for closure types.
There is a conceptual roadmap that the Swift core team has laid out for restoring named closure parameters at some point in the future, but no timeline for implementation that I am aware of:
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160711/024331.html

Swift creating a function that runs another function that was implemented while called.(Not that complex)

Hello i am trying to create a kickass function to show alerts and run it's function. Buuut unfortunately Xcode and i am getting confused in here:
buttonAction:Array<(Any) -> Any)>
Expected '>' to complete generic argument list
func callAlert(_ view: UIViewController, title:String, message:String, buttonName:Array<String>, buttonAction:Array<(Any) -> Any)>) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
for index in 0..<buttonName.count{
alert.addAction(UIAlertAction(title: buttonName[index], style: .default, handler: { action in
switch action.style{
case .default:
print("default")
buttonAction()
case .cancel:
print("cancel")
case .destructive:
print("destructive")
}}))}
view.present(alert, animated: true, completion: nil)
}
How do i call function? Please check below:
callAlert(self,
title: "Donate type",
message: "Thanks for your support!",
buttonName: ["Buy me a coffee!","Something"]
)
First of all I highly recommend to implement the method as an extension of UIViewController.
Second of all I'd prefer presentAlert() over callAlert()
Third of all rather than two arrays for buttons and actions use one array of tuples for title, style and action.
By the way unspecified type (Any) -> Any is very, very bad because UIAlertAction handlers are clearly ((UIAlertAction) -> Void)?
Finally add an optional completion handler
extension UIViewController {
func presentAlert(title: String,
message: String,
alertActions: [(title: String, style: UIAlertAction.Style, action: ((UIAlertAction) -> Void)?)],
completion: (() -> Void)? = nil) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
for action in alertActions {
alert.addAction(UIAlertAction(title: action.title, style: action.style, handler: action.action))
}
self.present(alert, animated: true, completion: completion)
}
}
And use it inside an UIViewController
let buyCoffeeAction : (UIAlertAction) -> Void = { action in
// do something
}
let somethingAction : (UIAlertAction) -> Void = { action in
// do something
}
presentAlert(title: "Donate type",
message: "Thanks for your support!",
alertActions: [(title: "Buy me a coffee!", style: .default, action: buyCoffeeAction),
(title: "Something", style: .destructive, action: somethingAction)],
completion: nil)

error cannot convert value of type `Void` to expected argument type `() -> Void` UIAlertController

Very often I have to show an alert to the user and I find myself writing the same code over and over again, so I built a convenience method.
When self.convenience.showAlertToUser() is called in viewDidLoad I get error for argument doThisAction cannot convert value of type Void to expected argument type () -> Void. I don't understand why, because I pass in an argument of that type. Also, I don't know if I am creating a retain cycle, so I would appreciate your help.
class ConvenienceMethods {
func showAlertToUser(alertMessage: String = "",actionOkTitle:String, actionCancelTitle:String, controller: UIViewController, cancelAction: Bool, doAction: #escaping (() -> Void)) {
let customAlert = UIAlertController(title: "", message: alertMessage, preferredStyle: .alert)
let actionCancel = UIAlertAction(title: actionCancelTitle, style: .cancel, handler: nil)
let actionOk = UIAlertAction(title: actionOkTitle, style: .default, handler: { (action: UIAlertAction) in
doAction()
})
if cancelAction == true {
customAlert.addAction(actionCancel)
}
customAlert.addAction(actionOk)
controller.present(customAlert, animated: true, completion: nil)
}
}
class ManageFeedbackTableViewController {
let convenience = ConvenienceMethods()
override func viewDidLoad() {
super.viewDidLoad()
let doThisAction = self.segueWith(id: "segueID")
self.convenience.showAlertToUser(alertMessage: "someMessage", actionOkTitle: "OK", actionCancelTitle: "No", controller: self, cancelAction: false, doAction: doThisAction)
}
//perform an action
func segueWith(id: String) -> Void{
self.performSegue(withIdentifier: id, sender: self)
}
}
Because you are to passing a reference to the function but the result itself.
Replace
let doThisAction = self.segueWith(id: "segueID")
By :
let doThisAction = { self.segueWith(id: "segueID") }
#bibscy,
doThisAction is a closure to which we can assign a block of code within "{ }" as follows:-
let doThisAction = { self.segueWith(id: "segueID") } which will work.

AWS Cognito doesn't call confirmSignUp when confirming user identity in Swift with Xcode

I finally managed to get the SignUp to work, but when trying to confirm the signup, I'm reaching a problem. Here is my code:
var user: AWSCognitoIdentityUser?
#IBAction func submitButton(_ sender: Any) {
guard let confirmationCodeValue = self.codeTextField.text, !confirmationCodeValue.isEmpty else {
let confirmationAlert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert)
confirmationAlert.addAction(UIAlertAction(title: "好", style: .default, handler: {action in
print("Try again!")
}))
self.present(confirmationAlert, animated: true, completion: nil)
return
}
self.user?.confirmSignUp(self.codeTextField.text!, forceAliasCreation: true).continue({[weak self] (task: AWSTask) -> Any? in
guard let strongSelf = self else { return nil }
DispatchQueue.main.async(execute: {
print("At least this is working...")
if let error = task.error {
let confirmationFailAlert = UIAlertController(title: (error as NSError).userInfo["__type"] as? String,
message: (error as NSError).userInfo["__type"] as? String,
preferredStyle: .alert)
confirmationFailAlert.addAction(UIAlertAction(title: "好",
style: .default,
handler: {action in
}))
self?.present(confirmationFailAlert, animated: true, completion: nil)
} else {
let confirmationSuccessAlert = UIAlertController(title: self?.alertTitleConfirmationComplete,
message:self?.alertMessageConfirmationComplete,
preferredStyle: .alert)
confirmationSuccessAlert.addAction(UIAlertAction(title: "好",
style: .default,
handler: {action in
self?.dismiss(animated: true, completion: nil)
}))
self?.present(confirmationSuccessAlert, animated: true, completion: nil)
}
})
return nil
})
}
The first part of this code works fine. If I type nothing in the space, I get an alertView telling me so. However, if I type anything in the space, nothing happens. The print statement "At least this is working..." never gets called. I've been staring at this code for a couple hours now trying to figure out what's wrong, and I feel like it's probably something simple, but as of now, I could use some help!
Thanks in advance!
I assume the code block above is not the full source, but be sure the optional, user, is "unencapsulated" and equal to an actual instance of AWSCognitoIdentityUser.
If it isn't, which I am assuming it is not, confirmSignUp won't know the username, sub, or have any information on the user it is "confirming".
I would recommend logging user and be sure that username is in fact a value within user.
I believe you set it equal to that instance type in the response to your AWSCognitoIdentityUserPool class signUp:password:userAttributes:validationData: call.
Check those values that are returned in AWSCognitoIdentityUserPoolSignUpResponse.

calling function from viewcontroller - parameters error - Swift2

I am having trouble calling the tweet function. I keep getting errors with the parameters. I also tried just (AnyObject) and got
Error: argument type does not conform to expected...
I am new to swift and not sure how to get this running. Tried everything I can think of. Thank you
// from GameScene
var vc = ViewController()
vc.tweetAction(sender: AnyObject)
//error: cannot create single-element tuple with an element label
//function in View Controller below
#IBAction func tweetAction(sender: AnyObject){
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter){
let tweetController = SLComposeViewController(forServiceType: SLServiceTypeTwitter)
tweetController.setInitialText("I Scored on this app")
self.presentViewController(tweetController, animated: true, completion: nil)
}
else{
let alert = UIAlertController(title: "Accounts", message: "Please log into your twitter to share", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
alert.addAction(UIAlertAction(title: "Settings", style: UIAlertActionStyle.Default, handler: { (UIAlertACtion) in
let settingsURL = NSURL(string:UIApplicationOpenSettingsURLString)
if let url = settingsURL{
UIApplication.sharedApplication().openURL(url)
}
}))
self.presentViewController(alert, animated: true, completion: nil)
}
}
You are passing a type to your method invocation instead of an instance. You also are including a label for the first parameter, which is incorrect. Try:
vc.tweetAction(self)
Try to change sender parameter type from AnyObject to UILabel
var vc = ViewController()
vc.tweetAction(yourUILabelInstance)
And don't forget to modify tweetAction function as well
#IBAction func tweetAction(sender: UILabel){
...
}