Unexpectedly found nil while unwrapping optional. - ios

I've narrowed down the error to this block of code. I need to define something at optional but I'm not sure where.
#IBAction func SignupWithFacebook(sender: AnyObject) {
var permissionsArray = ["user_about_me", "user_birthday", "email"]
PFFacebookUtils.logInWithPermissions(permissionsArray, block: { (user: PFUser?, error: NSError!) -> Void in
if (user == nil) {
let errormessage = error.userInfo!["error"] as NSString
var facebookLoginError = UIAlertController(title: "Error While Logging", message: "\(errormessage)", preferredStyle: .Alert)
var okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
facebookLoginError.addAction(okButton)
self.presentViewController(facebookLoginError, animated: true, completion: nil)
}
})
}
Any help would be greatly appreciated.

Your code assumes that if user is nil then error will exist. I don't know if you can make that guarantee. Try this instead:
#IBAction func SignupWithFacebook(sender: AnyObject) {
let permissionsArray = ["user_about_me", "user_birthday", "email"]
PFFacebookUtils.logInWithPermissions(permissionsArray) { (user, error) -> Void in
if user == nil {
if let e = error {
let errormessage = e.userInfo!["error"] as NSString
let facebookLoginError = UIAlertController(title: "Error While Logging", message: "\(errormessage)", preferredStyle: .Alert)
let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
facebookLoginError.addAction(okButton)
self.presentViewController(facebookLoginError, animated: true, completion: nil)
}
}
}
}

Related

Consecutive declarations on a line must be separated by ';' with regards to createstripeuser

I am trying to call function "createStripeUser" from my viewcontroller. It shows errors
Here is my viewcontroller :-
import UIKit
import FirebaseFirestore
import FirebaseAuth
import Stripe
import FirebaseFunctions
class SignUpViewController: UIViewController {
var paymentContext = STPPaymentContext()
#IBOutlet weak var email: UITextField!
#IBOutlet weak var password: UITextField!
#IBOutlet weak var passwordConfirm: UITextField!
#IBAction func signUpAction(_ sender: Any) {
if password.text != passwordConfirm.text {let alertController = UIAlertController(title: "Password Incorrect", message: "Please re-type 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().createUser(withEmail: email.text!, password: password.text!){ (user, error) in if error == nil {
self.performSegue(withIdentifier: "signupToHome", sender: self)
}
else{
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)
}
}
}
}
Functions.functions().httpsCallable("createStripeUser").call(["email": email]) { (result, error) in **// error - Consecutive declarations on a line must be separated by ';'**
if let error = error {
debugPrint(error.localizedDescription)
return
}
self.dismiss(animated: true)
}
}
Here is a screenshot of the errors
The functions are fully deployed in Firebase. why is it showing error?
You've added the call to Cloud Functions after the closing } of your signUpAction function. This is much easier to see if you re-format your code:
func signUpAction(_ sender: Any) {
if password.text != passwordConfirm.text {
let alertController = UIAlertController(title: "Password Incorrect", message: "Please re-type 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().createUser(withEmail: email.text!, password: password.text!){
(user, error) in if error == nil {
self.performSegue(withIdentifier: "signupToHome", sender: self)
}
else{
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)
}
}
}
}
Functions.functions().httpsCallable("createStripeUser").call(["email": email]) {
(result, error) in **// error - Consecutive declarations on a line must be separated by ';'**
if let error = error {
debugPrint(error.localizedDescription)
return
}
self.dismiss(animated: true)
}
My guess is that you want the Functions.functions().httpsCallable("createStripeUser") call to be up above the } above it, so that it's part of the signUpAction function.

Data is not being inserted under the node of user UID in Firebase in Swift 3

When I save data under userID the data is not being stored into the Firebase and give error unexpectedly found nil while unwrapping an optional value, however when I use childByAutoID the data is being stored successfully. Help me to save under userID node. Here I have explained that when I create the user under signup action this is happening.
#IBAction func createAccountAction(_ sender: Any) {
if self.emailTextField.text == "" || self.passwordTextField.text == "" {
let alertController = UIAlertController(title: "Error", message: "Please enter your email and password", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
} else if (self.passwordTextField.text != self.retypePasswordfield.text) {
let alertController = UIAlertController(title: "Error", message: "Password does not match", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
} else {
ref.child("user_registration").setValue(["username": self.fullName.text, "email": self.emailTextField.text,"contact": self.numberText.text, "city": self.myCity.text, "state": self.countryText.text, "gender": genderGroup, "blood": bloodGroup])
FIRAuth.auth()?.createUser(withEmail: emailTextField.text!, password: passwordTextField.text!) { (user, error) in
if error == nil {
FIRAuth.auth()?.currentUser!.sendEmailVerification(completion: { (error) in
})
print("You have successfully signed up")
let alertController = UIAlertController(title: "Successful!", message: "Email Verification link sent", preferredStyle: .alert)
let alertActionOkay = UIAlertAction(title: "Okay", style: .default) { (action) in
let vc = self.storyboard?.instantiateViewController(withIdentifier: "LoginFirstViewController")
self.present(vc!, animated: true, completion: nil)
}
alertController.addAction(alertActionOkay)
self.present(alertController, animated: true, completion: nil)
} else {
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)
}
}
}
}
Only for reference
This is the current working code for me
On signUp Button
// Create new User
FIRAuth.auth()?.createUser(withEmail: self.tfEmail.text!, password: self.tfPassword.text!, completion: { (user, error) in
if error == nil{ // IF NO ERROR
let astrContact = self.strDialCode + " " + self.tfMobileNumber.text!
// Dict to add user data in firebase Db
let aDBDict : [String : String] = ["userName": self.tfFullName.text!,
"userEmail": self.tfEmail.text!,
"userContact": astrContact,
"userCountry": self.strCode,
"userID": (user?.uid)!]
// Add data in DB
ref?.child("Customer/\(String(describing: (user?.uid)!)/userProfileDetails").setValue(aDBDict)
DispatchQueue.main.async(execute: { () -> Void in
// goto home VC
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navController = storyboard.instantiateViewController(withIdentifier: "MainController")
if let window = AppDelegate.getAppDelegate().window {
window.rootViewController = navController
}
})
}
else{ // If error in creating new user
print("error in creating new user")
print(error!)
}
})
In appDelegate
extension AppDelegate {
class func getAppDelegate() -> AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
}

“Thread 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)”?

This is my swift code
i will get above error on this line : guard (newUser["status"] as! Int != 0)
#IBAction func signInButton(_ sender: UIButton) {
if validator(){
DispatchQueue.global(priority: DispatchQueue.GlobalQueuePriority.default).async(execute: {
let datas:[String:String] = ["email":self.emailField.text!,"name": self.nameField.text!,"password" : self.passwordField.text!]
DispatchQueue.main.async {
SwiftSpinner.show("Signin' in...")
}
let newUser:NSDictionary = self.marketcloud!.createUser(datas)
print(newUser)
DispatchQueue.main.async {
SwiftSpinner.hide()
guard (newUser["status"] as! Int != 0) else {
let alertController = UIAlertController(title: "Error", message: "Email already in use. Try with a different one!", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Close",
style: UIAlertActionStyle.destructive,
handler: nil))
self.present(alertController, animated: true, completion: nil)
return
}
let alertController = UIAlertController(title: "Ok!", message: "User created successfully!", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.default, handler: {(action:UIAlertAction) in
UserData.setLastRegisteredUser(self.emailField.text!, password: self.passwordField.text!);
print("Setted UserData \n \(UserData.getLastRegistedUserEmail(),UserData.getLastRegisteredUserPassword())")
//returns to the login view
let next = self.storyboard!.instantiateViewController(withIdentifier: "viewController") as! ViewController
next.downloadProducts = false
next.load = true
self.navigationController?.pushViewController(next, animated: true)
}));
self.present(alertController, animated: true, completion: nil)
}
})
}
}
Try to understand how guard works.
The condition must be an optional binding with let or a boolean expression
guard let status = newUser["status"] as? Int, status != 0 else { ...
And no parentheses in Swift.

Optimizing a CloudKit sign-in on app launch with error handling. How can I better handle the optional chaining? Swift 3.0/Xcode 8.1

Is there a cleaner, swiftier solution to handle the optional chaining happening in my code below? I'm setting up the user for CloudKit access in my custom function runCKsetup():
func runCKsetup() {
container.requestApplicationPermission(.userDiscoverability) { (status, error) in
guard error == nil else {
if let error = error as? NSError {
if let errorDictionary: AnyObject = error.userInfo as? Dictionary<String, AnyObject> as AnyObject? {
let localizedDescription = errorDictionary["NSLocalizedDescription"]! as! String!
if localizedDescription! == "This operation has been rate limited" {
// Create an alert view
let alert = UIAlertController(title: "Network Error", message: localizedDescription!, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Test for Connection", style: UIAlertActionStyle.default) { (action) in
self.runCKsetup()
})
self.present(alert, animated: true, completion: nil)
} else {
// Create an alert view
let alert = UIAlertController(title: "Sign in to iCloud", message: localizedDescription!, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default) { (action) in
})
self.present(alert, animated: true, completion: nil)
}
}
}
return
}
if status == CKApplicationPermissionStatus.granted {
self.container.fetchUserRecordID { (recordID, error) in
guard error == nil else {
self.presentMessageAlert((error?.localizedDescription)!, title: "Error", buttonTitle: "Ok")
return }
guard let recordID = recordID else { return }
self.container.discoverUserIdentity(withUserRecordID: recordID, completionHandler: { (info, fetchError) in
//do something with the users names: e.g. print("\(info?.nameComponents?.givenName) \(info?.nameComponents?.familyName)")
})
}
}
}
}

why is the block of code inside func call is not executed?

I am trying to implement an Xmpp client into my application.I am planning on using the following code inside my application but some part of the code doesn't seem to be executed which prevents me to connect to a server. https://github.com/processone/xmpp-messenger-ios
I am trying to connect to a server with my jabberID and password but for some this code is never executed:
if let _ = error {
let alertController = UIAlertController(title: "Sorry", message: "An error occured: \(error)", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (UIAlertAction) -> Void in
//do smt
}))
self.presentViewController(alertController, animated: true, completion: nil)
} else {
self.dismissViewControllerAnimated(true, completion: nil)
}
Here is the whole code that is related to the problem:
#IBAction func validate(sender: AnyObject) {
if OneChat.sharedInstance.isConnected() {
OneChat.sharedInstance.disconnect()
usernameTextField.hidden = false
passwordTextField.hidden = false
validateButton.setTitle("Validate", forState: UIControlState.Normal)
} else {
OneChat.sharedInstance.connect(username: self.usernameTextField.text!, password: self.passwordTextField.text!) {(stream, error) -> Void in
if let _ = error {
let alertController = UIAlertController(title: "Sorry", message: "An error occured: \(error)", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (UIAlertAction) -> Void in
//do smt
}))
self.presentViewController(alertController, animated: true, completion: nil)
} else {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
}
}
public typealias OneChatConnectCompletionHandler = (stream: XMPPStream, error: DDXMLElement?) -> Void
public func connect(username username: String, password: String, completionHandler completion:OneChatConnectCompletionHandler) {
if isConnected() {
streamDidConnectCompletionBlock = completion
self.streamDidConnectCompletionBlock!(stream: self.xmppStream!, error: nil)
return
}
if (username == "kXMPPmyJID" && NSUserDefaults.standardUserDefaults().stringForKey(kXMPP.myJID) == "kXMPPmyJID") || (username == "kXMPPmyJID" && NSUserDefaults.standardUserDefaults().stringForKey(kXMPP.myJID) == nil) {
streamDidConnectCompletionBlock = completion
streamDidConnectCompletionBlock!(stream: self.xmppStream!, error: DDXMLElement(name: "Please set crendentials before trying to connect"))
return
}
if username != "kXMPPmyJID" {
setValue(username, forKey: kXMPP.myJID)
setValue(password, forKey: kXMPP.myPassword)
}
if let jid = NSUserDefaults.standardUserDefaults().stringForKey(kXMPP.myJID) {
xmppStream?.myJID = XMPPJID.jidWithString(jid)
} else {
streamDidConnectCompletionBlock = completion //was false
streamDidConnectCompletionBlock!(stream: self.xmppStream!, error: DDXMLElement(name: "Bad username"))
}
if let password = NSUserDefaults.standardUserDefaults().stringForKey(kXMPP.myPassword) {
self.password = password
} else {
streamDidConnectCompletionBlock = completion //was false
streamDidConnectCompletionBlock!(stream: self.xmppStream!, error: DDXMLElement(name: "Bad password"))
}
try! xmppStream!.connectWithTimeout(XMPPStreamTimeoutNone)
streamDidConnectCompletionBlock = completion
}
Perhaps, you are expecting a time-out that never will happened (configuration of the library)
I had the same problem and, finally, I fount that my problem was hostname and port. Did you try to use something like this:
let usuario = "name#domain.com";
OneChat.sharedInstance.connect(username: usuario, password: pass) { (stream, error) -> Void in
if let _ = error {
let alertController = UIAlertController(title: "Sorry", message: "An error occured: \(error)", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (UIAlertAction) -> Void in
//do something
}))
self.presentViewController(alertController, animated: true, completion: nil)
} else {
print("I did it!")
}
}

Resources