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

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.

Related

Change UILabel Text via UIAlertAction

I want to have an alert action change the text of a UILabel in my View. Code below:
#IBAction func statusChange(_ sender: UIButton){
let playalert = UIAlertController(title: "OPERATION: \(sender.accessibilityIdentifier!) NOT POSSIBLE", message: "Convert op to PLAY mode to proceed", preferredStyle: .alert)
let recordalert = UIAlertController(title: "OPERATION: \(sender.accessibilityIdentifier!) NOT POSSIBLE", message: "Convert op to STOP mode to proceed", preferredStyle: .alert)
let statechangealert = UIAlertController(title: "OPERATION: \(sender.accessibilityIdentifier!) WILL NOW PROCEED", message: "", preferredStyle: .alert)
let stopAction = UIAlertAction(title: "Convert", style: .default, handler: { action in
self.statusDVR.text = "STOP"//"\(sender.accessibilityIdentifier!)"
})
let continueAction = UIAlertAction(title: "Continue", style: .default, handler: { action in
self.statusDVR.text = ""//"\(sender.accessibilityIdentifier!)"
})
let returnAction = UIAlertAction(title: "Return", style: .default, handler: { action -> Void in
})
playalert.addAction(stopAction)
playalert.addAction(returnAction)
recordalert.addAction(stopAction)
recordalert.addAction(returnAction)
statechangealert.addAction(continueAction)
//record was tapped, check if DVR stopped first
if (sender.tag == 5 && pwrStat == true ) {
//if not stopped send alert
if statusDVR.text != "STOP" {
self.present(recordalert, animated:true, completion: nil)
//if user tapped returned action
if statusDVR.text != "STOP" {
self.present(statechangealert, animated:true, completion: nil)
} else {
return
}
} else {
statusDVR.text = "RECORD"
}
The stopAction should convert a UILAbel called statusDVR in the view controller, but it doesn't do it.
I haven't tried implementing the other Actions yet, because I am stuck trying to figure out why my UILabel's text won't change. Thank you for any help :)
First of all, this code makes no sense:
if statusDVR.text != "STOP" {
self.present(recordalert, animated:true, completion: nil)
if statusDVR.text != "STOP" {
self.present(statechangealert, animated:true, completion: nil)
That code tries to present two alerts at the same time. That is illegal.
I think you think that when you say
self.present(recordalert, animated:true, completion: nil)
...your code magically comes to a stop while the user interacts with the alert and then proceeds after the user dismisses the alert. That’s not the case. Your code never magically stops; it just keeps right on going.
As for the actual question you asked about, the problem is simply that what you're doing is illegal:
playalert.addAction(stopAction)
playalert.addAction(returnAction)
recordalert.addAction(stopAction)
recordalert.addAction(returnAction)
No! You cannot take one UIAlertAction and somehow magically "share" it between two different UIAlertControllers. Every UIAlertController needs UIActions that belong to it alone. In other words, do not call addAction on the same UIAlertAction twice.
Just to demonstrate more simply, try running this code:
let action1 = UIAlertAction(title: "Test", style: .default) {
_ in print("test")
}
let alert1 = UIAlertController(title: "Hello", message: nil, preferredStyle: .alert)
let alert2 = UIAlertController(title: "Hello2", message: nil, preferredStyle: .alert)
alert1.addAction(action1)
alert2.addAction(action1)
self.present(alert1, animated: true, completion: nil)
The alert appears, you tap the Test button, the alert disappears — but nothing prints in the console. Now comment out the next to last line:
// alert2.addAction(action1)
... and run the code again. This time, when you tap Test, "test" appears in the console.

Code not finishing the function, it is ending execution halfway through

My code is as follows:
#IBAction func clicked(_ sender: Any) {
let ref = Database.database().reference()
let pass = password.text
var firpass = ""
var bool = false;
ref.child(name.text as! String).child("password").observeSingleEvent(of: .value, with: { dataSnapshot in
firpass = dataSnapshot.value as! String
if firpass == pass {
bool = true
print("in here")
}
})
print(bool)
if bool {
self.sendname = name.text!
let vc = DatabaseTableViewController(nibName: "DatabaseTableViewController", bundle: nil)
vc.finalName = self.sendname
navigationController?.pushViewController(vc, animated: true)
performSegue(withIdentifier: "username", sender: self)
} else {
let alert = UIAlertController(title: "Error", message: "Incorrect username or password", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
"in here" gets printed, but bool is never printed and the alert is showing. Why does my code not enter the if bool block and output the alert?
Data is loaded from Firebase asynchronously, since it may take a while. Instead of making your app wait for the data (which would be a bad user experience), your main code continues while the data is being loaded, and then once the data is available your closure is called.
This explains the behavior you're seeing: by the time your runs, the hasn't run yet.
the solution is as simple as it is initially confusing and annoying: any code that needs the data from the database must be inside the closure, or be called from there.
So for example:
ref.child(name.text as! String).child("password").observeSingleEvent(of: .value, with: { dataSnapshot in
firpass = dataSnapshot.value as! String
if firpass == pass {
bool = true
print("in here")
}
print(bool)
if bool {
self.sendname = name.text!
let vc = DatabaseTableViewController(nibName: "DatabaseTableViewController", bundle: nil)
vc.finalName = self.sendname
navigationController?.pushViewController(vc, animated: true)
performSegue(withIdentifier: "username", sender: self)
} else {
let alert = UIAlertController(title: "Error", message: "Incorrect username or password", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
})
Also see:
Firebase with Swift 3 counting the number of children
Array of struct not updating outside the closure
getting data out of a closure that retrieves data from firebase (showing examples with custom callbacks and delegates)
How to reload data after all Firebase calls finished? (showing how to use a dispatch group)
Finish all asynchronous requests before loading data? (another example using a dispatch group)
Also you have to set variable bool to false when you are navigating to next view controller after login. So that you login again and if password is wrong then you can not navigate to next page and only it shows alert for wrong password.

if nameTextField.text!.isEmpty not working?

Im trying to check if a textFieldis empty, and if it is a popup should show:
func missingText (title: String, message: String)
{
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
#IBAction func registerButton(_ sender: UIButton) {
//Display errormsg for missing entry
if nameTextField.text!.isEmpty
{
missingText(title: "Error", message: "Missing name")
}
}
Nothing is happening when the textfield is empty. I (think) I have the exact same code in another app, and that's working fine.. What am I missing?
The nameTextFieldis hooked up.
I had a similar problem once, It turned out that instead of using the placeholder for description for the textfield, I used the Text. Both are located in Attributes inspector for the textField. So, if u use the Textfor description, the textField will never be empty.
I guess textfield text is nil. so that it may not be calling. try with below code
#IBAction func registerButton(_ sender: UIButton) {
guard let text = textField.text, text != "" else{
missingText(title: "Error", message: "Missing name")
return
}
// do stuff with text,
}
u can try this one this might will help you . nametextfield.text , !text.empty

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){
...
}

"fatal error: unexpectedly found nil while unwrapping an Optional value" in Standardized Social Media Sharing Method

I am trying to create a standardized social media sharing method inside my SocialMediaSharingDelegate. Specifying an individual social media service like I do in the facebookShare method works perfectly fine. So to extend this I created an enum with the possible service types and the shareOn method accepts any valid service name to perform sharing.
It seems straight forward. However, when I run the code and click on a button that calls the shareOn method I get a runtime error. The error "fatal error: unexpectedly found nil while unwrapping an Optional value" occurs on the line let serviceViewController... right after the guard statement.
It also works fine if I replace socialMediaService.associatedService() with SLServiceTypeFacebook on that line which is strange because socialMediaService.associatedService() is used without issue in the guard statement.
I can just create separate functions for each service for now but that is not ideal in terms of code reuse.
import Foundation
import UIKit
import Social
enum SocialMediaEnum : String {
case Twitter = "SLServiceTypeTwitter"
case Facebook = "SLServiceTypeFacebook"
// This internal enum function returns the SLServiceType associated with the current enum value
func associatedService() -> String {
var serviceName: String
switch self {
case .Twitter:
serviceName = "SLServiceTypeTwitter"
case .Facebook:
serviceName = "SLServiceTypeFacebook"
}
return serviceName
}
}
class socialMediaSharing : SocialMediaSharingDelegate {
func shareOn(let socialMediaService: SocialMediaEnum, sender: subclassedUIButton?, currentViewController: UIViewController) {
guard SLComposeViewController.isAvailableForServiceType(socialMediaService.associatedService()) else {
let alert = UIAlertController(title: "Accounts", message: "Please login to a Twitter account to tweet.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
currentViewController.presentViewController(alert, animated: true, completion: nil)
return
}
let serviceViewController :SLComposeViewController = SLComposeViewController(forServiceType: socialMediaService.associatedService())
if let imageUrl = sender?.urlString {
if let url:NSURL = NSURL(string: imageUrl as String) {
serviceViewController.addURL(url)
}
}
currentViewController.presentViewController(serviceViewController, animated: true, completion: nil)
}
func facebookShare(sender: subclassedUIButton?, currentViewController: UIViewController) {
guard SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook) else {
let alert = UIAlertController(title: "Accounts", message: "Please login to a Facebook account to share.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
currentViewController.presentViewController(alert, animated: true, completion: nil)
return
}
let shareToFacebook :SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
if let imageUrl = sender?.urlString {
if let url:NSURL = NSURL(string: imageUrl as String) {
shareToFacebook.addURL(url)
}
}
currentViewController.presentViewController(shareToFacebook, animated: true, completion: nil)
}
}
SLServiceTypeTwitter and SLServiceTypeFacebook are keywords so they should not have quotation marks in the switch statement. The actual values they hold are "com.apple.social.(service name)".