Parse Password reset function - ios

I am trying to use the password reset for parse in my ios app and I can't seem to find any tutorial on the best method in swift on how to implement this into a button action but find nothing.
Anyone know a great place to look?
This is what I have so far
#IBAction func resetPassword(sender: AnyObject) {
[PFUser requestPasswordResetForEmailInBackground:
self.loginEmail.text
block:^(BOOL succeeded, NSError *error)
{
[APP.hud hide:YES];
if (!succeeded)
{
NSString *msg = #"Could not connect. Try again later.";
[UIAlertView ok:msg];
return;
}
[UIAlertView minimalistMessageFor:3.0
title:nil
message:#"Your password has been sent to your email address."
then:^{ }];
[self begin];
}];
}
I get a Expected expression in container literal error on this one on the PFUser line.

I use the following in the app I'm working on, which pop ups a alert box to enter your email and confirms the result in a new alert box:
#IBAction func resetPasswordPressed(sender: AnyObject) {
let titlePrompt = UIAlertController(title: "Reset password",
message: "Enter the email you registered with:",
preferredStyle: .Alert)
var titleTextField: UITextField?
titlePrompt.addTextFieldWithConfigurationHandler { (textField) -> Void in
titleTextField = textField
textField.placeholder = "Email"
}
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Default, handler: nil)
titlePrompt.addAction(cancelAction)
titlePrompt.addAction(UIAlertAction(title: "Reset", style: .Destructive, handler: { (action) -> Void in
if let textField = titleTextField {
self.resetPassword(textField.text)
}
}))
self.presentViewController(titlePrompt, animated: true, completion: nil)
}
func resetPassword(email : String){
// convert the email string to lower case
let emailToLowerCase = email.lowercaseString
// remove any whitespaces before and after the email address
let emailClean = emailToLowerCase.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
PFUser.requestPasswordResetForEmailInBackground(emailClean) { (success, error) -> Void in
if (error == nil) {
let success = UIAlertController(title: "Success", message: "Success! Check your email!", preferredStyle: .Alert)
let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
success.addAction(okButton)
self.presentViewController(success, animated: false, completion: nil)
}else {
let errormessage = error!.userInfo!["error"] as! NSString
let error = UIAlertController(title: "Cannot complete request", message: errormessage as String, preferredStyle: .Alert)
let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
error.addAction(okButton)
self.presentViewController(error, animated: false, completion: nil)
}
}
}
It's also smart to convert the email users register with to lowercase before you sync it with parse in a similar way as I show with the reset method.
If you want to put in a activity indicator, so that users see that the app is busy in between the actions, create the following two methods and call Pause() in the Reset action and Restore() just before or after the if/else in the resetPassword method. Also include the following class variable:
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
func pause(){
activityIndicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 50, 50))
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
UIApplication.sharedApplication().beginIgnoringInteractionEvents()
}
func restore(){
activityIndicator.stopAnimating()
UIApplication.sharedApplication().endIgnoringInteractionEvents()
}

It looks like you are mixing up swift with objective-c. I'm assuming that you are in a swift class. Try the following:
#IBAction func resetPassword(sender: AnyObject) {
PFUser.requestPasswordResetForEmailInBackground(self.loginEmail.text)
var alert = UIAlertController(title: nil, message: "Your password has been sent to your email address.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}

I had a similar problem, the problem is that the doc is apparently not updated on that
PFUser.requestPasswordResetForEmailInBackground("email#example.com")
The following thing worked for me
PFUser.requestPasswordResetForEmailInBackground("email#example.com", nil)
Hope that this will help

Related

How to put a success or error alert inside an options alert?

I have a problem trying to put an alert message after completing the action. The application crashes.
#IBAction func deleteAccountAction(_ sender: Any) {
let userID = prefs.value(forKey: "userId") as! String
print("user id: \(userID)")
let alert = UIAlertController(title: "Delete account", message: "Are you sure you want to delete your account?, This action cannot be reversed.", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
// ...
}
let okayAction = UIAlertAction(title: "OK", style: .default) { (action) in
RestAPIManager.sharedInstance.deleteAccount(userID: userID){
(json, error) in
if(json != JSON.null){
print(json)
if(json["success"] == true){
//here i want succes alert
}else{
self.errorAlert()
}
}else{
}
}
}
alert.addAction(okayAction)
alert.addAction(cancelAction)
self.present(alert, animated: true)
}
func errorAlert(){
var dialogMessage = UIAlertController(title: "Error", message: "Error", preferredStyle: .alert)
self.present(dialogMessage, animated: true, completion: nil)
}
I tried to put an alert message after the action but I can't.
is solved needs to be async.
DispatchQueue.main.async {
self.errorAlert()
}

Adding Activity Indicator after Clicking "LOGIN"?

I would like to add an Activity Indicator for my Login VC so that users will see that spinner thing once they click the "login" button. I have done multiple attempts and failed. Even if I put in codes for hiding the activity indicator, it just keeps animating even before clicking the "login" button. I deleted those codes, and have my original codes below (without activity indicator).
import UIKit
import Firebase
class LoginViewController: UIViewController {
var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageView = UIImageView(frame: view.bounds)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.image = #imageLiteral(resourceName: "background")
imageView.center = view.center
view.addSubview(imageView)
self.view.sendSubview(toBack: imageView)
}
//Outlets
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
//Login Action
#IBAction func loginAction(_ sender: AnyObject) {
if self.emailTextField.text == "" || self.passwordTextField.text == "" {
//Alert to tell the user that there was an error because they didn't fill anything in the textfields because they didn't fill anything in
let alertController = UIAlertController(title: "Error", message: "Please enter an email and password.", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
} else {
Auth.auth().signIn(withEmail: self.emailTextField.text!, password: self.passwordTextField.text!) { (user, error) in
if error == nil {
//Print into the console if successfully logged in
print("You have successfully logged in")
//Go to the HomeViewController if the login is sucessful
let vc = self.storyboard?.instantiateViewController(withIdentifier: "Home")
self.present(vc!, animated: true, completion: nil)
} else {
//Tells the user that there is an error and then gets firebase to tell them the error
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
}
so I know the first step is probably dragging the activity indicator to the VC in Storyboard, but what's next?
You need to create a IBOutlet of dragged UIActivityIndicator. Then in viewDidLoadfunc hide this UIActivityIndicator with it's IBOutlet. When you click on Login Button, then unhide this activityIndicator and hide again, once receive response from login.
Create an IBOUtlet of your activity indicator from Storyboard to your Viewcontroller -
You can then in your ViewDidLoad or your storyboard set the below property
activityIndicator.hidesWhenStopped = true;
And when you want to start it, call
activityIndicator.startAnimating();
And to stop it from animating -
activityIndicator.stopAnimating();
The same way you created your IBOutlets of UITextField, create one with your UIActivityIndicator. Make sure your indicator's hidesWhenStopped is set to true in the storyboard.
Then animate it before calling your signin method, and stop it on the completion handler
#IBOutlet weak var activityIndicator: UIActivityIndicator!
//...
activityIndicator.startAnimating()
Auth.auth().signIn(withEmail: self.emailTextField.text!, password: self.passwordTextField.text!) { (user, error) in {
activityIndicator.stopAnimating()
//...
}
You can create UIActivityIndicatorView in your class programmatically & customize it in viewDidLoad
var activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
// Add below code in viewDidLoad
self.activityIndicator.hidesWhenStopped = true
self.activityIndicator.center = view.center
self.view.addSubView(self.activityIndicator)
Now do start & stop animating whereever you need
//Login Action
#IBAction func loginAction(_ sender: AnyObject) {
self.activityIndicator.startAnimating()
if self.emailTextField.text == "" || self.passwordTextField.text == "" {
//Alert to tell the user that there was an error because they didn't fill anything in the textfields because they didn't fill anything in
let alertController = UIAlertController(title: "Error", message: "Please enter an email and password.", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
} else {
Auth.auth().signIn(withEmail: self.emailTextField.text!, password: self.passwordTextField.text!) { (user, error) in
self.activityIndicator.stopAnimating()
if error == nil {
//Print into the console if successfully logged in
print("You have successfully logged in")
//Go to the HomeViewController if the login is sucessful
let vc = self.storyboard?.instantiateViewController(withIdentifier: "Home")
self.present(vc!, animated: true, completion: nil)
} else {
//Tells the user that there is an error and then gets firebase to tell them the error
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
In your storyboard, you can find checkbox.
startsAnimating
HidesWhenStops(check this in your storyboard.)
#IBOutlet weak var activityIndicator: UIActivityIndicator!
#IBAction func loginAction(_ sender: AnyObject) {
activityIndicator.startAnimating()
if self.emailTextField.text == "" || self.passwordTextField.text == "" {
//Alert to tell the user that there was an error because they didn't fill anything in the textfields because they didn't fill anything in
let alertController = UIAlertController(title: "Error", message: "Please enter an email and password.", preferredStyle: .alert)
activityIndicator.stopAnimating()
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
} else {
Auth.auth().signIn(withEmail: self.emailTextField.text!, password: self.passwordTextField.text!) { (user, error) in
if error == nil {
//Print into the console if successfully logged in
print("You have successfully logged in")
activityIndicator.stopAnimating()
//Go to the HomeViewController if the login is sucessful
let vc = self.storyboard?.instantiateViewController(withIdentifier: "Home")
self.present(vc!, animated: true, completion: nil)
} else {
//Tells the user that there is an error and then gets firebase to tell them the error
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
}
An alternative Approach. Adding the UIActivityViewController programatically:
In the LoginViewController class add
let myActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
In the viewDidLoad() add the following
myActivityIndicator.hidesWhenStopped = true
myActivityIndicator.center = view.center
view.addSubview(myActivityIndicator)
In #IBAction func loginAction(_ sender: AnyObject) in the else part
add
activityIndicator.startAnimating()
Auth.auth().signIn(withEmail: self.emailTextField.text!, password: self.passwordTextField.text!) { (user, error) in {
activityIndicator.stopAnimating()
I have written a class to use progress hud properly. You just need to drag and drop the class to your project...
https://github.com/emraz/ERProgressHud
For showing progress hud write ..
ERProgressHud.show()
For hiding progress hud write ..
ERProgressHud.hide()
In your code ..
//Login Action
#IBAction func loginAction(_ sender: AnyObject) {
if self.emailTextField.text == "" || self.passwordTextField.text == "" {
//Alert to tell the user that there was an error because they didn't fill anything in the textfields because they didn't fill anything in
let alertController = UIAlertController(title: "Error", message: "Please enter an email and password.", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
return
}
else {
ERProgressHud.show()
Auth.auth().signIn(withEmail: self.emailTextField.text!, password: self.passwordTextField.text!) { (user, error) in
ERProgressHud.hide()
if error == nil {
//Print into the console if successfully logged in
print("You have successfully logged in")
//Go to the HomeViewController if the login is sucessful
let vc = self.storyboard?.instantiateViewController(withIdentifier: "Home")
self.present(vc!, animated: true, completion: nil)
} else {
//Tells the user that there is an error and then gets firebase to tell them the error
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
}

Change UIAlertController message or title during its presentation

Is posible change the title or message text of UIAlertController while its ViewController is presenting.
For example I present an alert when a user press a button with this message:
"Waiting for redeem code"
Then I use Alamofire to make a request and get the code, after I have it I want to change the message from alert without dissmising and presenting it again, for example the new message text is it:
"Your redeem code is : ########"
Updated
Here is my code:
#IBAction func offerAction(_ sender: UIButton) {
var code: String = "Generating códe"
let message: String = "El código para redimir esta oferta es: \(code)"
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: "Accept", style: .default, handler: nil)
let redirect = UIAlertAction(title: "Website", style: .default) { (_) in
// TODO open url web
}
if offer.redeemOfferOnline == .yes {
alert.addAction(redirect)
}
alert.addAction(okAction)
present(alert, animated: true, completion: nil)
offer.code.getRedeemCode(id: offer.id) { (success, data) in
if success {
code = data
alert.message = message
// TODO end the code of changing the message of alert
}
}
}
this is possible of course, please check the following:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let alertController = UIAlertController(title: "My Title", message: "My Message", preferredStyle: .alert)
present(alertController, animated: true, completion: nil)
// Do your queries and get your new title and then set the new title
alertController.title = "Your new title"
}
}
It is possible to change the title and/or text AND animate the change, thusly:
[UIView transitionWithView: alertController.view
duration: 0.3
options: UIViewAnimationOptionTransitionCrossDissolve
animations: ^(void) {
alertController.message = newMessage;
}
completion: nil];
Or in Swift:
UIView.transition(with: alertController.view,
duration: 0.3,
options: .transitionCrossDissolve,
animations: { alertController.message = newMessage }
)
Just define you alertcontroller as:
var controller:UIAlertController?
Then initialize your alert controller like this:
controller = UIAlertController(title: "Title", message: "Yo", preferredStyle: .alert)
self.present(controller!, animated: true, completion: nil)
Now when you get the data from server, call this:
self.controller?.title = "New Title"
displayMyAlertMessage(userMessage: "Keshav Gera");
func displayMyAlertMessage(userMessage: String)
{
let alert = UIAlertController(title: "Success", message: userMessage, preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: nil)
let imgTitle = UIImage(named:"imgTitle.png")
let imgViewTitle = UIImageView(frame: CGRect(x: 10, y: 10, width: 30, height: 30))
imgViewTitle.image = imgTitle
alert.view.addSubview(imgViewTitle)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}

click on a label in Swift

I want to make the label that on click on it to make call to number. I know that iOS has this option, but how can I do it in Swift?
I found just how to do it in ObjC:
-(IBAction)callPhone:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:2135554321"]];
}
Can anyone help me with it?
UIApplication.sharedApplication().openURL(NSURL(string: "tel://2135554321"))
example
if let CallURL:NSURL = NSURL(string:"tel://\(yourMobileNUmber)") {
let application:UIApplication = UIApplication.sharedApplication()
if (application.canOpenURL( CallURL)) {
application.openURL( CallURL);
}
else
{
// your number not valid
let tapAlert = UIAlertController(title: "Alert!!!", message: "Your mobile number is invalid", preferredStyle: UIAlertControllerStyle.Alert)
tapAlert.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil))
self.presentViewController(tapAlert, animated: true, completion: nil)
}
}
Type-2
// add gesture to your Label
var tapGesture = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
yourLabelName.userInteractionEnabled=true
yourLabelName.addGestureRecognizer(tapGesture)
// handle the function of UILabel
func handleTap(sender:UITapGestureRecognizer){
if let CallURL:NSURL = NSURL(string:"tel://\(yourMobileNUmber)") {
let application:UIApplication = UIApplication.sharedApplication()
if (application.canOpenURL( CallURL)) {
application.openURL( CallURL);
}
else
{
// your number not valid
let tapAlert = UIAlertController(title: "Alert!!!", message: "Your mobile number is invalid", preferredStyle: UIAlertControllerStyle.Alert)
tapAlert.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil))
self.presentViewController(tapAlert, animated: true, completion: nil)
}
}
}

Problems with getting text from UIAlertView textfield

In my application I want a alert with a textfield. After clicking on "Done" I want to save the textfield input in a String. After clicking on "Cancel" I want only to close the alert. I've created my alert like this:
var alert = UIAlertView()
alert.title = "Enter Input"
alert.addButtonWithTitle("Done")
alert.alertViewStyle = UIAlertViewStyle.PlainTextInput
alert.addButtonWithTitle("Cancel")
alert.show()
let textField = alert.textFieldAtIndex(0)
textField!.placeholder = "Enter an Item"
println(textField!.text)
The alert looks like this:
I want to know how to get the text from the textfield, and how to create events for the "Done" button and the "Cancel" button.
You may go with UIAlertController instead of UIAlertView.
I've already implemented and tested too using UIAlertController for what you actually want. Please try the following code
var tField: UITextField!
func configurationTextField(textField: UITextField!)
{
print("generating the TextField")
textField.placeholder = "Enter an item"
tField = textField
}
func handleCancel(alertView: UIAlertAction!)
{
print("Cancelled !!")
}
var alert = UIAlertController(title: "Enter Input", message: "", preferredStyle: .Alert)
alert.addTextFieldWithConfigurationHandler(configurationTextField)
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler:handleCancel))
alert.addAction(UIAlertAction(title: "Done", style: .Default, handler:{ (UIAlertAction) in
print("Done !!")
print("Item : \(self.tField.text)")
}))
self.presentViewController(alert, animated: true, completion: {
print("completion block")
})
You will have to implement the UIAlertViewDelegate's
optional func alertView(_ alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int)
For SWIFT 3
#IBAction func ForgotPassword(_ sender: Any) {
let alertController = UIAlertController(title: "Email?", message: "Please input your email:", preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "Confirm", style: .default) { (_) in
if let field = alertController.textFields![0] as? UITextField {
// store and use entered data
} else {
print("please enter email id")
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }
alertController.addTextField { (textField) in
textField.placeholder = "Email"
}
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
}
I hope it will help someone else :)
For iOS 8+ you should use UIAlertController instead of UIAlertView. To support iOS 7 you should implement (UIAlertViewDelegate):
func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int)
{
//...
let textField = alertView.textFieldAtIndex(0)
}

Resources