PFUser currentUser not saving in iOS7 - ios

I am using the below code to save the currently logged in user with custom field. I allow the user to fill in information and then save. I used both the save methods on my own threading using GCM and used the saveInBackgrounWithBlock. On iOS8, this works ok but on iOS7 saving never happens and the completion block is never called. Any ideas? Thanks
if PFUser.currentUser() != nil {
PFUser.currentUser().setObject(installation, forKey: "installation")
PFUser.currentUser().saveInBackgroundWithBlock({ (bool: Bool, error: NSError?) -> Void in
if(error != nil) {
let alert = UIAlertView(title: "Problem Saving", message: "Make sure you are connecte to the internet and try again", delegate: nil, cancelButtonTitle: "OK")
alert.show();
}
})
}
Update 1: I noticed that deleting the app resolves the issue temporarily. However, after signing out and signing in with other user (i.e. changing the current user), the issue will pop up again.
Update 2: The issue seems to be coming from PFInstallation somehow. Using addUniqueObject causes issues. After calling this method, any saves stops working iOS7. Even on the PFUser. The PFUser has the installation setup and vice versa. An array of them.
Update 3: Seems like it's not just the addUniqueObject, but any setObject on the PFInstallation.currentInstallation. Help!

you should check your first param (isSuccess) as well:
if (bool == YES && error != nil) -> success
else -> failure

It took me a long while to realise, and even though I never actually found a solution to the problem itself, I found a workaround. I was saving the currentUser in the currentInstallation and the currentInstallation in the currentUser. This was causing issues when saving. I also saved channels on the currentInstallation by sending an array of channels directly instead of using addUniqueObject.
let installation = PFInstallation.currentInstallation()
installation.channels = channels;
installation.saveInBackground()

Related

UITextField Password Autofill Confirmation

I've been playing around with UITextField's password autofill feature for logging into my backend, and as of yet I've been unable to find a way to actually confirm or validate that the user has authenticated via TouchID to access their passwords.
Am I crazy or because this feature is so baked in to iOS, we can't actually check to see if the user was able to successfully authenticate?
Or am I missing some kind of delegate call in the LocalAuthentication API that gets called?
TIA for your help.
I use a method like this with a callback with the result, sometimes I store off the result to look up later on in the session. Not sure if this is what you're looking for, or if you needed something more advanced. This is part of a class for me where I have made my own delegates that I call on authentication or failure as well.
private func authenticateUser(completion: #escaping (Bool)->()) {
let context = LAContext()
var error:NSError?
let reason = "Authenticate for access"
context.localizedFallbackTitle = ""
if(context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error)){
context.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason, reply: { (success, error) -> Void in
if(success){
completion(true)
} else {
completion(false)
}
})
}
}

Updating to Xcode 7 Beta 5 & Swift 2 produced multiple errors

I updated Xcode to the new Xcode 7 beta 5. In doing so, it converted to Swift 2, but then created even more errors. Right now, I am completely stuck, and don't know what to do, because although all my errors are gone, my app will not work correctly.
My problem is this:
if(self.myOutput3 as? NSObject == true) {
print("IT IS TRUE")
PFUser.logInWithUsernameInBackground(self.myOutput1 as! String, password: "xxx") { (user: PFUser?, error: NSError?) -> Void in
if error == nil {
print("It Worked!")
// self.presentViewController(destViewController, animated: true, completion: nil)
let instillation = PFInstallation.currentInstallation()
instillation["user"] = PFUser.currentUser()
instillation.saveInBackgroundWithBlock(nil)
self.performSegueWithIdentifier("toTimeline", sender: self)
} else {
// self.enterButton.enabled = false
self.errorAlert()
print("Couldn't log in...")
}
}
} else {
print("IT IS FALSE")
self.performSegueWithIdentifier("continueTheSignIn", sender: self)
// self.move()
}
The program will perform the toTimeline segue, but not the continueTheSignIn . I don't see any logical reason that this is not working. Could anyone point me in the right direction?
Also, I am having an error in my messages feature.
cell.textView!.linkTextAttributes = [NSForegroundColorAttributeName:cell.textView!.textColor]
This is giving me the error "Cannot assign a value of type '[String : UIColor?]' to a value of type '[String: AnyObject]!'
I was not previously getting this error in Swift / Xcode 6.4, so I don't know how to fix it.
Additionally, once I bypass this to get into my app to see if my other features are working, most of my UITableViews are not displaying any information. One is, however the rest load the correct amount of rows, but display nothing. What could this be? Also, no Parse pictures are being displayed correctly either. These are even more concerning than the other problems...
Here is the picture after I deleted and re added the segue under a diff. name.
Parse wont support the beta version . it needs a full version . I have contacted them based on a similar issue . They said they will update the parse to work with xcode7 once the full version of xcode7 is released.

Parse saveInBackgroundWithBlock crashes on iOS

I am adding some data into my parse class (table) successfully.
After saving is successfully completed (I can see the data on website), my app crashes without leaving any message on console. I tried to get a message by using "Enable Zombie Objects" setting. This is the message I am getting which has nothing to do what I am doing:
-[UIActivityIndicatorView release]: message sent to deallocated instance 0x126d16780
I do not have any UIActivityIndicatorView in my whole project.
This is how I save my data:
var currentUser = PFUser.currentUser()!
var userCase = PFObject(className: "Case")
userCase.relationForKey("user").addObject(currentUser)
userCase["caseCode"] = "test_code"
userCase.saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
// The object has been saved.
println("saved")
} else {
// There was a problem, check error.description
println("error occurred: \(error?.description)")
}
}
Swift SDK version: 1.7.5
Xcode version: 6.4
Has anybody have ever faced with such problem?
UPDATE: This error does not occur on simulator (tested on iPhone 5, iPhone 5S, iPhone 6) and does not occur on device at first run.
Tried removing and re-installing the app.
UPDATE 2: Removing PFFacebookUtils.initializeFacebookWithApplicationLaunchOptions(launchOptions) or changing it to PFFacebookUtils.initialize() from AppDelegate fixes the issue but I think I need to use initializeFacebookWithApplicationLaunchOptions(launchOptions). I have another problem now.
You may do the following.
1) Go to PFFacebookUtils.h
2) change:
(void)initializeFacebookWithApplicationLaunchOptions:(NSDictionary *)launchOptions;
To:
(void)initializeFacebookWithApplicationLaunchOptions:(PF_NULLABLE NSDictionary *)launchOptions;
It was originally posted here

Parse.com PFUser signUpInBackgroundWithBlock: block not being called on first tap

i am developing an iOS-App with Swift and the parse.com framework and have a big problem with registering new users.
The block of "signUpInBackgroundWithBlock" is not being called on the first tap, although the new user is getting registered. When i am tapping the button a second time, the block gets finally called and i get an error, that the username is already registered.
var newUser = PFUser()
newUser.username = registerView.nicknameTextField.text.trim()
newUser.email = registerView.emailTextField.text
newUser.password = registerView.passwordTextField.text
newUser.signUpInBackgroundWithBlock {
(succeeded: Bool, error: NSError!) -> Void in
self.registerCompletionBlock(succeeded, error: error)
}
Is someone having the same problem and knows a solution for this strange behaviour?
Thanks!
Edit:
The completion block should call the "registerCompletionBlock()" function:
func registerCompletionBlock(succeeded: Bool, error: NSError!) {
if error == nil {
let subscriptionStoryboard = UIStoryboard(name: "Subscription", bundle: nil)
let viewcontroller: UIViewController = subscriptionStoryboard.instantiateInitialViewController() as UIViewController
self.presentViewController(viewcontroller, animated: true, completion: nil)
} else {
if let errorString = error.userInfo?["error"] as? NSString {
println(errorString)
if error.userInfo?["code"] as Float == 202{
let alert = UIAlertView(title: "vergeben", message: "name vergeben", delegate: nil, cancelButtonTitle: "abbrechen")
alert.show()
}
}
}
}
I tried the solution posted previously (eliminating PFUser.enableAutomaticUser()), and the issue persisted.
In case anyone else is still looking for a solution to this issue, try changing the if error == nil to if succeeded == true in the block of signUpInBackground. This worked for me and all is functional in backend.
Its calling at first time, but its taking a little time for calling this .. because its sending data on server in asynchronous. Asynchronous never block the main thread..
Because : -
Asynchronous never block the main thread waiting for a network response.
Asynchronous can be either synchronous on a separate thread, or scheduled in the run loop of any thread.
Asynchronous can be either synchronous on a separate thread, or scheduled in the run loop of any thread.
Synchronous blocks main thread until they complete request.
Because you call the method asynchronous, it takes some time to do it and your main thread doesn't wait for the method to finish. So you should, if you want to show a message or perform a segue, after the registration, put it inside the completion-block:
newUser.signUpInBackgroundWithBlock {
(succeeded: Bool!, error: NSError!) -> Void in
if error == nil {
// Perform a segue, show a message or whatever you want
} else {
let errorString = error.userInfo["error"] as NSString
// Show the errorString somewhere and let the user try again.
}
}
Also if you don't want to do it asynchronous, you can call the signUp() method(without the inBackgroundWithBlock. That way the application waits for the signup to finish until it continues.
i figured it out. Problem was, that i used PFUser.enableAutomaticUser() in the AppDelegate. I removed that line and the signup-block works flawlessly now!

Use Parse.com Data in iOS 8 Notification Center widget

I am trying to download a few strings from parse.com inside of a Notification Center widget.
Therefore I first need to sign the user in to parse. First I am loading the credentials, which are saved from the app itself in the NSUserDefaults (I know about the safety aspect.). This step works fine, but when I am performing the following code, the widget says, that the loading of data is not possible.
func signUserIn(username: String, password: String) {
PFUser.logInWithUsernameInBackground(username, password:password) {
(user: PFUser!, error: NSError!) -> Void in
if (user != nil) {
SMKeychainService.saveToken(password)
var defaults = NSUserDefaults(suiteName: "group.xxx.xxx")
defaults.setObject(username, forKey: "UsernameKey")
defaults.synchronize()
self.delegate?.signedIn!(true)
} else {
self.delegate?.signedIn!(false)
}
}
}
Has anyone of you tried to load data from parse.com inside of an widget and how did you do it. I canĀ“t even load the data, because like I mentioned the widget crashes at the sign in of the user.
The app itself has no problems with signing in to parse and loading the data.
I solved the problem
I did not implemented Parse.setApplicationId("xxx", clientKey: "xxx"), now I implemented it in viewDidLoad and the code works!
Setting the
Parse.setApplicationId(appID, clientKey: clientKey)
in the AppDelegate does not work for the extension. Use this code in the viewDidLoad of the extension and it works fine.

Resources