UIAlertView' was deprecated in iOS 9.0 - ios

I have tried several ways to use UIAlertController,instead of UIAlertView, but I cannot make the alert go. Thanks in advance for any further suggestions. I am a newbie.
UIAlertView' was deprecated in iOS 9.0: UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead
Here is my code :
import MessageUI
class SecondViewController: UIViewController,MFMailComposeViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func sendmail(sender: UIButton) {
let mailComposeViewController = configuredMailComposeViewController()
if MFMailComposeViewController.canSendMail() {
self.presentViewController(mailComposeViewController, animated: true, completion: nil)
} else {
self.showSendMailErrorAlert()
}
}
func configuredMailComposeViewController() -> MFMailComposeViewController {
let mailComposerVC = MFMailComposeViewController()
mailComposerVC.mailComposeDelegate = self // Extremely important to set the --mailComposeDelegate-- property, NOT the --delegate-- property
mailComposerVC.setToRecipients(["blabla#gmail.com"])
mailComposerVC.setSubject("App Feedback")
mailComposerVC.setMessageBody("Feature request or bug report?", isHTML: false)
return mailComposerVC
}
func showSendMailErrorAlert() {
let sendMailErrorAlert = UIAlertView(title: "Could Not Send Email", message: "Your device could not send e-mail. Please check e-mail configuration and try again.", delegate: self, cancelButtonTitle: "OK")
sendMailErrorAlert.show()
}
// MARK: MFMailComposeViewControllerDelegate Method
func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {
controller.dismissViewControllerAnimated(true, completion: nil)
}
}

use UIAlertController
Here a example:
//Create the AlertController
let actionSheetController: UIAlertController = UIAlertController(title: "Alert", message: "Swiftly Now! Choose an option!", preferredStyle: .Alert)
//Create and add the Cancel action
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
//Do some stuff
}
actionSheetController.addAction(cancelAction)
//Create and an option action
let nextAction: UIAlertAction = UIAlertAction(title: "Next", style: .Default) { action -> Void in
//Do some other stuff
}
actionSheetController.addAction(nextAction)
//Add a text field
actionSheetController.addTextFieldWithConfigurationHandler { textField -> Void in
//TextField configuration
textField.textColor = UIColor.blueColor()
}
//Present the AlertController
self.presentViewController(actionSheetController, animated: true, completion: nil)

Try something like this...
let sendMailErrorAlert = UIAlertController(title: "Could Not Send Email", message: "Your device could not send e-mail. Please check e-mail configuration and try again.", preferredStyle: .Alert)
self.presentViewController(sendMailErrorAlert, animated: true, completion: nil)

let alertController = UIAlertController(title: "Could Not Send Email
", message: "Your device could not send e-mail. Please check e-mail configuration and try again.", preferredStyle: .Alert)
Use UIAlertController
After initializing add actions to alertcontroller.
UIAlertCOntroller is subclass of UIViewController. So you can use self.presentViewController method show alert on current controller.
            
 

Related

How to create a reusable alert view used across different view controllers?

in the simple language: can we create that alert Box as a reusable method
i want to made 1 Alert box in to the function.
like this.
// this code has separate file
import UIKit
struct AlertView {
public func showAlertBox(title: String, message: String) -> UIAlertController {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
}))
return alert
}
}
and here is my caller ViewController file code.
#IBAction func submitPressed(_ sender: Any) {
let alertView = AlertView()
let alert = alertView.showAlertBox(title: "Hours Added", message: "Hours have been updated")
alert.present(alert, animated: true) {
self?.dismiss(animated: true, completion: nil)
self?.timeSubmitted = true
self?.performSegue(withIdentifier: "unwindToMyHours", sender: nil)
}
}
You need alert action to performing ok action.
You can modify your code by this
Here are the helper functions.
struct AlertView {
public static func showAlertBox(title: String, message: String, handler: ((UIAlertAction)->Void)?) -> UIAlertController {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: handler))
return alert
}
}
extension UIAlertController {
func present(on viewController: UIViewController, completion: (() -> Void)? = nil) {
viewController.present(self, animated: true, completion: completion)
}
}
Usage
class ViewController: UIViewController {
#IBAction func submitPressed(_ sender: Any) {
AlertView.showAlertBox(title: "Hours Added", message: "Hours have been updated") { [weak self] action in
// Okay action code
}.present(on: self) { [weak self] in
self?.dismiss(animated: true, completion: nil)
self?.timeSubmitted = true
self?.performSegue(withIdentifier: "unwindToMyHours", sender: nil)
}
}
}
Note: self is dismissing so might be your alert is not presenting. You can present your alert on top most view controller. see this
Yes, you can create a shared alert controller. I would suggest making it a static method of your struct, or even a global function. It's silly to create an instance of your struct only to invoke a method that doesn't need any instance variables:
public static func alertBox(title: String, message: String) -> UIAlertController {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
}))
return alert
}
}
And then you'd invoke it by saying
let alert = AlertView.alertBox(title: "title",message: "message" )
(Your function doesn't show the alert, it just creates it. I would therefore suggest naming it alertBox, not 'showAlertBox`.
Yes, you can use a shared alert controller. What I would suggest is making the AlertView struct, a singleton. You can change the struct as follows
struct AlertView {
// Shared instance
static let shared: AlertView = AlertView()
// Private initializer to prevent creating of new instances
private init() {}
public func showAlertBox(title: String, message: String) -> UIAlertController {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { _ in
}))
return alert
}
}
By doing so, you will be able to create just one instance of AlertView and you have to use that single instance in your program. That way you won't have to create new instances of AlertView every time you need to display an alert. You can invoke it using,
let alert = AlertView.shared.showAlertBox(title: "Hours Added", message: "Hours have been updated")
Edit - You can refer this medium article to understand the singleton design patter
The best way is to perform simple encapsulation through extension, and complex encapsulation just loses applicability
example:
let alertVC = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
.addActionTitles(titles) { (alertVC, action) in
let actionIdx = alertVC.actions.firstIndex(of: action)
DDLog(actionIdx)
}
self.present(alertVC, animated: true, completion:{})
code:
public let kTitleSure = "Yes"
public let kTitleCancell = "No"
/// contentViewController
public let kAlertContentViewController = "contentViewController"
#objc public extension UIAlertController{
///add UIAlertAction
#discardableResult
func addActionTitles(_ titles: [String]? = [kTitleCancell, kTitleSure], handler: ((UIAlertController, UIAlertAction) -> Void)? = nil) -> Self {
titles?.forEach({ (string) in
let style: UIAlertAction.Style = string == kTitleCancell ? .cancel : .default
self.addAction(UIAlertAction(title: string, style: style, handler: { (action) in
handler?(self, action)
}))
})
return self
}
///add textField
#discardableResult
func addTextFieldPlaceholders(_ placeholders: [String]?, handler: ((UITextField) -> Void)? = nil) -> Self {
if self.preferredStyle != .alert {
return self
}
placeholders?.forEach({ (string) in
self.addTextField { (textField: UITextField) in
textField.placeholder = string
handler?(textField)
}
})
return self
}
#discardableResult
func setContent(vc: UIViewController, height: CGFloat) -> Self {
setValue(vc, forKey: kAlertContentViewController)
vc.preferredContentSize.height = height
preferredContentSize.height = height
return self
}
}
github

How to get UIViewController in a singleton?

I'm using a singleton class to validate a network response. Inside the function (validResponse()) I'm calling in the singleton, I call another function which pops up an alert box, to let the user know there was an error.
The function inside my singleton class:
func validResponse(data: Data?, response: URLResponse?, error: Error?, viewController: UIViewController, context: String?) -> Bool {
...
DispatchQueue.main.async {
AlertHelper.showAlertWrapper(viewController: viewController, alertTitle: "Error", alertMessage: self.genericError)
}
}
The AlertHelper code:
class AlertHelper {
static func showAlertWrapper(viewController: UIViewController, alertTitle: String, alertMessage: String) {
let alertController = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert);
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil);
alertController.addAction(okAction);
viewController.present(alertController, animated: true, completion: nil);
}
}
Calling validResponse():
let result = self.networkHelper.validResponse(data: data, response: response, error: error, viewController: self, context: "Delete section")
In the above instance self is not going to work, and is just temporarily there until I figure out what to do. I understand I could just pass the relevant UIViewController in viewController, like I did for showAlertWrapper. However this is a bit messy.
Is there some way I can reference the currently present view controller in my singleton class, so that I dont have to pass it in validResponse()?
You may want to get the top most view controller currently showing in your app. You can do this by retrieving the top most view controller when your singleton wants to display an error.
class AlertHelper {
static func showAlertWrapper(alertTitle: String, alertMessage: String) {
let alertController = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert);
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil);
alertController.addAction(okAction);
if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
// viewController should now be your topmost view controller
viewController.present(alertController, animated: true, completion: nil);
}
}
}
And call your showAlertWrapper:
AlertHelper.showAlertWrapper(alertTitle: "Error", alertMessage: self.genericError)
A workaround and maybe swiftier way would be to have the showAlertWrapperin the UIViewController:
extension UIViewController {
func showAlertWrapper(title: String, message: String) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert);
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil);
alertController.addAction(okAction);
present(alertController, animated: true, completion: nil);
}
}
Then you would just do
DispatchQueue.main.async {
viewController.showAlertWrapper(title: "Error", message: self.genericError)
}

How to create uialertcontroller in global swift

I'm trying to create uialertcontroller in Config.swift file as follow.
static func showAlertMessage(titleStr:String, messageStr:String) -> Void {
let window : UIWindow?
let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert);
self.window!.presentViewController(alert, animated: true, completion: nil)
}
problem is I've found problem in self.window!.
Type 'Config' has no member 'window'
Please let me know how to solve that issue.
swift
Here's what I used, this is the same as #penatheboss answered, just add the ability of adding actions and handlers.
extension UIViewController {
func popupAlert(title: String?, message: String?, actionTitles:[String?], actions:[((UIAlertAction) -> Void)?]) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
for (index, title) in actionTitles.enumerated() {
let action = UIAlertAction(title: title, style: .default, handler: actions[index])
alert.addAction(action)
}
self.present(alert, animated: true, completion: nil)
}
}
Just make sure actionTitles and actions array the same count. Pass nil if you don't need any action handler closure.
self.popupAlert(title: "Title", message: " Oops, xxxx ", actionTitles: ["Option1","Option2","Option3"], actions:[{action1 in
},{action2 in
}, nil])
Objective C:
Add the category for UIViewController
UIViewController+PopAlert.h
#import <UIKit/UIKit.h>
#interface UIViewController (UIViewControllerCategory)
- (void) popAlertWithTitle: (NSString*) title message: (NSString*) message actionTitles:(NSArray *) actionTitles actions:(NSArray*)actions;
#end
UIViewController+PopAlert.m
#import "UIViewController+PopAlert.h"
#implementation UIViewController (UIViewControllerCategory)
- (void) popAlertWithTitle: (NSString*) title message: (NSString*) message actionTitles:(NSArray *) actionTitles actions:(NSArray*)actions {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
[actionTitles enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
UIAlertAction *action = [UIAlertAction actionWithTitle:obj style:UIAlertActionStyleDefault handler:actions[idx]];
[alert addAction:action];
}];
[self presentViewController:alert animated:YES completion:nil];
}
#end
Usage:
#import UIViewController+PopAlert.h
...
[super viewDidDisappear:animated];
NSArray *actions = #[^(){NSLog(#"I am action1");}, ^(){NSLog(#"I am action2");}];
[self popAlertWithTitle:#"I am title" message:#"good" actionTitles:#[#"good1", #"good2"] actions:actions];
self.window would mean that there's a window object in this class, and it's not the case.
You would need to use your let window : UIWindow? with window?.presentViewController(alert, animated: true, completion: nil), but this won't help, since this window does not actually represent any existing window, and it's not a view controller anyway.
So I suggest you pass the actual view controller you'll be using to the method:
static func showAlertMessage(vc: UIViewController, titleStr:String, messageStr:String) -> Void {
let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert);
vc.presentViewController(alert, animated: true, completion: nil)
}
and you call it from a class where a UIViewController object is available.
Details
Swift 5.1, Xcode 11.3.1
Global UIAlertController With UIViewController Extension
extension UIViewController{
// Global Alert
// Define Your number of buttons, styles and completion
public func openAlert(title: String,
message: String,
alertStyle:UIAlertController.Style,
actionTitles:[String],
actionStyles:[UIAlertAction.Style],
actions: [((UIAlertAction) -> Void)]){
let alertController = UIAlertController(title: title, message: message, preferredStyle: alertStyle)
for(index, indexTitle) in actionTitles.enumerated(){
let action = UIAlertAction(title: indexTitle, style: actionStyles[index], handler: actions[index])
alertController.addAction(action)
}
self.present(alertController, animated: true)
}
}
Usage
Alert
self.openAlert(title: "alert",
message: "add your message",
alertStyle: .alert,
actionTitles: ["Okay", "Cancel"],
actionStyles: [.default, .cancel],
actions: [
{_ in
print("okay click")
},
{_ in
print("cancel click")
}
])
ActionSheet
self.openAlert(title: "actionsheet",
message: "add your message",
alertStyle: .actionSheet,
actionTitles: ["Okay", "Cancel"],
actionStyles: [.default, .cancel],
actions: [
{_ in
print("okay click")
},
{_ in
print("cancel click")
}
])
I suggest creating an extension:
extension UIViewController {
func showAlertMessage(titleStr:String, messageStr:String) {
let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert)
self.presentViewController(alert, animated: true, completion: nil)
}
}
You can try this, please add below code in AppDelegate.swift file.
static func showAlertView(vc : UIViewController, titleString : String , messageString: String) ->()
{
let alertView = UIAlertController(title: titleString, message: messageString, preferredStyle: .alert)
let alertAction = UIAlertAction(title: "ok", style: .cancel) { (alert) in
vc.dismiss(animated: true, completion: nil)
}
alertView.addAction(alertAction)
vc.present(alertView, animated: true, completion: nil)
}
and call showAlertView method from any viewcontroller
AppDelegate.showAlertView(vc: self, titleString: "testTitle", messageString: "test msg")
I am suggest you write this code, but if you really need, try this:
static func showAlertMessage(titleStr:String, messageStr:String) -> Void {
let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert);
if let viewController = UIApplication.sharedApplication().windows.first?.rootViewController as UIViewController? {
viewController.presentViewController(alert, animated: true, completion: nil)
}
}
At least it won't break down.
#Eric D better answer.
I created a alerMessage class .I can call any where in my application
//Common Alert Message Class
class AlertMessage {
internal static var alertMessageController:UIAlertController!
internal static func disPlayAlertMessage(titleMessage:String, alertMsg:String){
AlertMessage.alertMessageController = UIAlertController(title: titleMessage, message:
alertMsg, preferredStyle: UIAlertControllerStyle.Alert)
AlertMessage.alertMessageController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default,handler: nil))
if let controller = UIApplication.sharedApplication().keyWindow?.rootViewController?.presentedViewController {
controller.presentViewController(AlertMessage.alertMessageController, animated: true, completion: nil)
}
else{
UIApplication.sharedApplication().delegate?.window!!.rootViewController?.presentViewController(AlertMessage.alertMessageController, animated: true, completion: nil)
}
return
}
}
Please refer the below GIT Example
https://github.com/amilaim/CommonAlertView
// ViewController.swift
// CommonAlertView
//
// Created by Amila Munasinghe on 4/25/17.
// Copyright © 2017 Developer Insight. All rights reserved.
//
import UIKit
class ViewController: UIViewController,AlertViewControllerDelegate {
#IBOutlet weak var AlertViewResultTextOutlet: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func ShowAlertAction(_ sender: Any) {
let alert = AlertViewController.sharedInstance
alert.delegate = self
alert.SubmitAlertView(viewController: self,title: "Developer Insight", message: "Please enter any text value")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func SubmitAlertViewResult(textValue : String) {
AlertViewResultTextOutlet.text = textValue
}
}
Common UIAlertViewController Implementation
import UIKit
protocol AlertViewControllerDelegate {
func SubmitAlertViewResult(textValue : String)
}
class AlertViewController {
static let sharedInstance = AlertViewController()
private init(){}
var delegate : AlertViewControllerDelegate?
func SubmitAlertView(viewController : UIViewController,title : String, message : String){
let alert = UIAlertController(title: title,
message: message,
preferredStyle: .alert)
// Submit button
let submitAction = UIAlertAction(title: "Submit", style: .default, handler: { (action) -> Void in
// Get 1st TextField's text
let textField = alert.textFields![0]
if(textField.text != "")
{
self.delegate?.SubmitAlertViewResult(textValue: textField.text!)
}
})
// Cancel button
let cancel = UIAlertAction(title: "Cancel", style: .destructive, handler: { (action) -> Void in })
// Add 1 textField and cutomize it
alert.addTextField { (textField: UITextField) in
textField.keyboardAppearance = .dark
textField.keyboardType = .default
textField.autocorrectionType = .default
textField.placeholder = "enter any text value"
textField.clearButtonMode = .whileEditing
}
// Add action buttons and present the Alert
alert.addAction(submitAction)
alert.addAction(cancel)
viewController.present(alert, animated: true, completion: nil)
}
}
What I'm using based on the solution by #William Hu:
func popup(caller:UIViewController, style:UIAlertControllerStyle? = UIAlertControllerStyle.alert,
title:String, message:String, buttonTexts:[String], buttonStyles:([UIAlertActionStyle?])? = nil,
handlers:[((UIAlertAction) -> Void)?], animated:Bool? = nil, completion: (() -> Void)? = nil) {
let alert = UIAlertController(title: title, message: message, preferredStyle: style!)
for i in 0..<buttonTexts.count {
alert.addAction(UIAlertAction(title: buttonTexts[i],
style: (buttonStyles == nil || i >= buttonStyles!.count || buttonStyles![i] == nil ?
UIAlertActionStyle.default : buttonStyles![i]!),
handler: (i >= handlers.count || handlers[i] == nil ? nil : handlers[i]!)))
}
caller.present(alert, animated: animated != nil ? animated! : true, completion: completion)
}
Single function gives Alert by default and can optionally be used for ActionSheet.
Arrays buttonTexts, buttonStyles and handlers can be of unequal sizes as per requirement.
Actions can be styled.
Animated can be specified.
Optional block can be specified to be executed when presentation finishes.
Usage:
popup(caller: self, style: UIAlertControllerStyle.alert,
title: "Title", message: "Message",
buttonTexts: ["Destructive", "Cancel", "OK"],
buttonStyles: [UIAlertActionStyle.destructive, UIAlertActionStyle.cancel],
handlers: [nil], animated: false)
You can use my Utility class created for Show Alert in Swift4. Its super easy to use just by writing single line of code:
Show Simple Alert
#IBAction func showDefaultAlert(_ sender: Any) {
Alert.showAlert(title:"Alert", message:"Default Alert")
}
Demo code link: https://github.com/smindia1988/EasyAlertInSwift4
If you want to present from AppDelegate windows you can use like this
UIApplication.sharedApplication().delegate?.window.rootViewController?.presentViewController(vc, animated: true, completion: nil)
This is also the way you can present on top of the View Controller available.
UIApplication.topViewController()?.present(alertViewController!, animated: true, completion: nil)

My UIAlertView won't dismiss from MasterViewController of UISplitViewController

I have the following code in my MasterViewController:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(false);
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
if((appDelegate.firstTime) != nil){
self.displayFirstTimeAlert()
}
}
It dutifully displays the alert:
func displayFirstTimeAlert(){
let message = "Please go to settings and set your preferred zipcode."
let alertView = UIAlertView(title: "Welcome", message: message, delegate: nil, cancelButtonTitle: "Dismiss")
alertView.show()
}
However when I touch Dismiss nothing happens? What is going on?
I don't know why the code you have above is not working, as I tested it and it does in fact dismiss. However, you shouldn't really be using UIAlertView any longer since it is deprecated... UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead
So try presenting the alert this way...
func displayFirstTimeAlert(){
let message = "Please go to settings and set your preferred zipcode."
var alert = UIAlertController(title: "Welcome", message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}

Parse Password reset function

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

Resources