I'm new to swift, and I'm having a difficult time figuring out why the code on https://www.parse.com/docs/ios_guide#users/iOS isn't working for me
var user = PFUser()
user.username = "myUsername"
user.password = "myPassword"
user.email = "email#example.com"
// other fields can be set just like with PFObject
user["phone"] = "415-392-0202"
user.signUpInBackgroundWithBlock {
(succeeded: Bool!, error: NSError!) -> Void in
if error == nil {
// Hooray! Let them use the app now.
} else {
let errorString = error.userInfo["error"] as NSString
// Show the errorString somewhere and let the user try again.
}
}
This line
user.signUpInBackgroundWithBlock
gives me the following error
Cannot invoke 'signUpInBackgroundWithBlock' with an argument list of type '((Bool!, NSError!) -> Void)'
I can copy and paste the code for Objective-C into my project and it works perfectly, but when I try to do the same with the Swift code. I get this error message. Is there something else I need to do to get it to work properly in Swift?
I found the solution in case others are having a similar problem. The code below seems to working just fine. Now I'm just curious to know why parse.com gives the above code in their documentation which doesn't actually work
user.signUpInBackgroundWithBlock {
(succeeded: Bool, error: NSError?) -> Void in
if error == nil {
// Hooray! Let them use the app now.
} else {
}
}
Related
I'm converting below code to Swift 3.
if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error:nil) {
// 2.
context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics,
localizedReason: "Logging in with Touch ID",
reply: { (success : Bool, error : NSError? ) -> Void in
// 3.
dispatch_async(dispatch_get_main_queue(), {
if success {
self.performSegueWithIdentifier("dismissLogin", sender: self)
}
if error != nil {
var message : NSString
var showAlert : Bool
// 4.
switch(error!.code) {
Step 4 does not work anymore on Xcode 8, Swift 3. So I could not do the following cases:
switch(error!.code) {
case LAError.AuthenticationFailed.rawValue:
message = "There was a problem verifying your identity."
showAlert = true
break;
Currently, it's seems there was no solution that I could find yet. Any suggestion, please let me know.
Thanks a lot!
First change your reply closure of evaluatePolicy method, in Swift 3 it is Error not NSError.
reply: { (success : Bool, error : Error? ) -> Void in
Second, change performSegue with identifier like this.
performSegue(withIdentifier: "dismissLogin", sender: self)
In Swift 3 you need to convert Error object to NSError or use _code with Error instance instead of code.
switch((error! as NSError).code)
OR
switch(error!._code)
You need to also change you dispatch syntax like this.
Dispatch.async.main {
//write code
}
This actually got a lot easier
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
localizedReason: "Logging in with Touch ID",
reply: { (success : Bool, error : Error? ) -> Void in
// 3.
DispatchQueue.main.async {
if success {
self.performSegueWithIdentifier("dismissLogin", sender: self)
}
if let error = error {
var message : NSString
var showAlert : Bool
// 4.
switch error {
case LAError.userCancel:
//do stuff
This is mostly from memory, but I think it is correct.
After the recent Swift update, I have been trying to debut a few lines of code and don't seem to be understanding what's wrong..
The lines are
PFGeoPoint.geoPointForCurrentLocationInBackground {
with the error message "Cannot invoke 'geoPointForCurrentLocationInBackground' with an argument list of type '((PFGeoPoint", NSError!) -> Void)'"
The second line is
PFUser.logInWithUsernameInBackground(username:usernameTextField.text, password:passwordTextField.text, target: self) {
With the error "Extra argument 'target' in call"
I've tried looking online and debugging these, but I honestly have no idea what's going on. It seems to be an error in the parse code and I'm not sure why that is...
Edit: I fixed second error I was having. code:
PFUser.logInWithUsernameInBackground(usernameTextField.text, password:passwordTextField.text) {
Start from Swift 1.2, the Failable Casts is introduced. you can use the PFGeoPoint.geoPointForCurrentLocationInBackground method like the following:
If you're quite sure that the downcasting will succeed, you can use as! to force the cast:
PFGeoPoint.geoPointForCurrentLocationInBackground {
(point:PFGeoPoint!, error:NSError!) -> Void in
if (error == nil) {
println(point)
} else {
println(error)
}
}
If you're not sure if the casting will succeed, just use the as? operator. By using as?, it returns an optional value, but in case the downcasting fails, the value will be nil.
PFGeoPoint.geoPointForCurrentLocationInBackground {
(point:PFGeoPoint?, error:NSError!) -> Void in
if (error == nil) {
if let myPoint = point {
println(myPoint)
}
} else {
println(error)
}
}
I am trying to implement sign up method in my app and now I have problems with parse. i am trying the following:
func signUpSend() {
var user = PFUser()
user.username = email.text
user.password = email.text
user.password = password.text
user.signUpInBackgroundWithBlock {
(succeeded: Bool!, error: NSError!) -> Void in
if error == nil {
// Hooray! Let them use the app now.
} else {
let errorString = error.userInfo["error"] as NSString
// Show the errorString somewhere and let the user try again.
}
}
}
the signUpInBackgroundWithBlock gives me an error "cannot invoke 'signUpInBackgroundWithBlock' with an argument list of type '((Bool!,NSError!) -> Void)' . I have tried to find answer in the parse docs, but thats exactly the code they advise to use. Anybody knows how to fix this?
Thanks!
Try changing:
(succeeded: Bool!, error: NSError!) -> Void in
to
(succeeded, error) -> Void in
I believe this change is required due to changes in Swift 1.2 update
I'm working on integrating touchID into my application. The process was fairly simple, but even just using my dummy data, it takes about 5 seconds after it authenticated my fingerprint, before it performs it's task.
Here's my code:
func requestFingerprintAuthentication() {
let context = LAContext()
var authError: NSError?
let authenticationReason: String = "Login"
if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &authError) {
context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: authenticationReason, reply: {
(success: Bool, error: NSError?) -> Void in
if success {
println("successfull signin with touchID")
self.emailInputField.text = "john.doe#gmail.com"
self.passwordInputField.text = "password"
self.signIn(self.signInButton)
} else {
println("Unable to Authenticate touchID")
}
})
}
}
even with the dummy data, it takes waaay too long.
When I login normally, by typing the email and the password into my inputfields, the signIn() function runs instantly.
To see if it was a problem with that. I tried replacing that, with 2 lines that simply takes me to the correct viewController. But it still takes several seconds after it's authenticated my fingerprint.
I know it's not the phone, nor touchID. Cause it runs my println("successfull signin with touchID") immediately. It's what comes after that, that for some reason takes several seconds for it to run?
Any help explaining this would be greatly appreciated!
The documentation states:
This method asynchronously evaluates an authentication policy.
You are running UI code on a thread that is not the main. Wrap your code to get it to perform on the main thread:
func requestFingerprintAuthentication() {
let context = LAContext()
var authError: NSError?
let authenticationReason: String = "Login"
if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &authError) {
context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: authenticationReason, reply: {
(success: Bool, error: NSError?) -> Void in
if success {
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
println("successfull signin with touchID")
self.emailInputField.text = "john.doe#gmail.com"
self.passwordInputField.text = "password"
self.signIn(self.signInButton)
})
} else {
println("Unable to Authenticate touchID")
}
})
}
}
I am having trouble trying to change Objective - C code to Swift. This is with the Parse framework. If anyone knows how the following code should be written in Swift, it would help me a lot.
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
//The registration was successful, go to the wall
[self performSegueWithIdentifier:#"SignupSuccesful" sender:self];
}
[NSObject: Anyobject]? does not have a member named subscript parse compile error will be thrown.
The code should be like that because userInfor maybe be nil.
user.signUpInBackgroundWithBlock {
(succeeded: Bool!, error: NSError!) -> Void in
if !(error != nil) {
// Hooray! Let them use the app now.
} else {
if let errorString = error.userInfo?["error"] as? NSString {
println(errorString)
}
}
}
Parse happens to have an example of this exact method in their documentation. I think they'll be OK if I excerpt it here:
user.signUpInBackgroundWithBlock {
(succeeded: Bool!, error: NSError!) -> Void in
if !error {
// Hooray! Let them use the app now.
} else {
let errorString = error.userInfo["error"] as NSString
// Show the errorString somewhere and let the user try again.
}
}
It would be something like this.
user.signUpInBackground {
(success: Bool!, error: NSError!) -> Void in
if !error {
[unowned self] in
self.performSegue("SignupSuccesful", sender:self);
}
Edit: Parse actually has Swift support. Here's a tutorial for it.
Edit2: You shouldn't refer to self inside a block. Use unowned self instead.