Parse: Erase User Account and Session - ios

When one deletes one's account, one's session should be deleted as well.
However the methods exposed by Parse to do this are mutually exclusive, such that:
PFUser.currentUser()?.deleteInBackground()
PFUser.logOut()
can't be called in parallel or in sequence, even with completion handlers.
How is this achieved, excluding Cloud Code?

Please convert below code in Swift if necessary, it will works fine with me :
[[PFUser currentUser] deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded && !error) {
[PFUser logOut];
}
else
{
NSLog(#"error: %#", error);
}
}];
Hope It's work fine...
Edit: Converted code to Swift
PFUser.currentUser()?.deleteInBackgroundWithBlock {
(succeeded: Bool, error: NSError?) -> Void in
if succeeded {
PFUser.logOut()
}
else {
NSLog("error: \(error)")
}

Related

Parse becomeInBackground is setting currentUser.sessionToken to null

I have an app that checks whether the current session is valid. So if you change the password on another phone, it will log you out of your other phones when you open the app. So, If there is a session token cached into [PFUser currentUser] I want to becomeInBackground with that token, and if it returns an error then that session is invalid and we should log out, else its valid and we have a new sessionToken. When I run this code I do not get any errors, and a user is returned with (null) for a .sessionToken
NSLog(#"Current Token: %#", [PFUser currentUser].sessionToken);
if ([PFUser currentUser].sessionToken) {
[PFUser becomeInBackground:[PFUser currentUser].sessionToken block:^(PFUser * _Nullable user, NSError * _Nullable error) {
if (error) {
NSLog(#"%#", error);
} else {
NSLog(#"Returned User Token: %#", user.sessionToken);
}
}];
}
this returns
Current Token: r:36ff500b036c041a37h9bab21f308741
Returned User Token: (null)
It's deleting the currentUser sessionToken! I have the most current Parse SDK (1.12.0) and I have no idea why it's doing this to me.
I believe this is happening as you are instructing the ParseSDK to become that other user, which looks like it doesn't work if it's the same as the current user (i.e. your session is valid).
I handle the session check a little bit differently. Instead, I refresh the user, then trap any errors and check for an invalid session. This works well :)
[[PFUser currentUser] fetchInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (error) {
NSLog(#"Error refreshing user %#", error.localizedDescription);
// check if the session token is invalid... force a logout!
if ([error.domain isEqualToString:PFParseErrorDomain] && error.code == kPFErrorInvalidSessionToken) {
dispatch_async(dispatch_get_main_queue(), ^{
[PFUser logOut];
// Show your login screen or whatever here
});
}
return;
}
}];

Facebook ios sdk (obj-c to swift) issue

I am trying to bring obj-c code to swift (facebook ios sdk), but autocomplete(intellisense) does not work in handler and I get an error (marked in code) : Set NSObject does not have a member named 'containsObject'
#IBAction func loginWithFacebook(sender: AnyObject) {
/*
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions:#[#"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
// Process error
} else if (result.isCancelled) {
// Handle cancellations
} else {
// If you ask for multiple permissions at once, you
// should check if specific permissions missing
if ([result.grantedPermissions containsObject:#"email"]) {
// Do work
}
}
}];
*/
let fbLoginManager = FBSDKLoginManager()
fbLoginManager.logInWithReadPermissions(["email"], handler: {
result, error in
if ((error) != nil){
}
else if (result.isCancelled){
} else {
if(result.grantedPermissions.containsObject("email")){ //<-- error here
}
}
})
}
Because Swift 1.2 automatically casts all NSSet objects (the ones that coming from external libs/sdks/frameworks etc...) to Set structure you need to call contains instead of containsObject for such things (doc).

How to prevent _User table from growing unnecessarily when using PFAnonymousUtils iOS SDK?

What is the best way to handle the scenario described below?
I am giving the user limited access (READONLY) when logged in anonymously.
The problem i am facing is that i am afraid is that the _User table would grow unnecessarily with redundant data.
Steps:
1. user logged in anonymously
2. clear cache
3. logged in anonymously again
problem : rows in _User table is added, older user is not removed.
Code:
+ (void) ParseLoginAnonymouslyWithBlock:(LoginAnonymousBLock)completionBlock {
// if ([PFUser currentUser] && [ParseUtilities isUserAnonymous]) {
// // user already logged in anonymously.
// // prevent duplicates in table
// completionBlock([PFUser currentUser], nil);
// return;
// }
[PFAnonymousUtils logInWithBlock:^(PFUser *user, NSError *error) {
// if (error) {
// completionBlock (user, error);
// } else {
// completionBlock (user, error);
// }
completionBlock(user, error);
}];
}
In View controller:
- (IBAction)loginGuestTapped:(id)sender {
NSLog(#"Guest Login tapped");
[ParseUtilities ParseLoginAnonymouslyWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(#"%#", &error);
} else {
NSLog(#"success");
// user logged in
NSLog(#"isanonymous: %i and %#", [ParseUtilities isUserAnonymous], [PFUser currentUser]);
}
}];
}
You could just add a 'latest_activity' flag into every user and update it when the user uses your app.
Then create a BackgroundJob (https://parse.com/docs/js/guide#cloud_code) and remove the anonymous users that are older than ~2weeks?
What you could also do is setup Push Notifications in you app and for each user that gave you a push notification token make sure the push notification does not 'reach' the recipient. In that case you can delete him since he doesn't even have the app installed anymore. (False positives are much lower in this case than the other, but you should combine them anyway!)

Writing completion block with Swift

I'm using Estimote's iOS SDK and I'm trying to write the following Objective-C code in Swift:
[self.beaconConnection writeMajor:newMajor completion:^(unsigned short major, NSError *error)
{
if (error)
{
NSLog(#"Error major write: %#", error.localizedDescription);
}
self.majorTextFiled.text = [NSString stringWithFormat:#"%i", major];
}];
I'm struggling with getting the completion block to work.
Here's what I have so far:
beaconConnection.writeMajor(major, completion: { value, error in
}
)
I accidentally had major as Int and it's supposed to be UInt16 for that method.
Here's the updated code:
beaconConnection.writeMajor(UInt16(major), completion: { value, error in
}
)

Checking type of error in LocalAuthentication

I know this may be a simple question but I can't find what I'm looking for on the internet. I'm using the LocalAuthentication framework from iOS 8 in my project and my code is here:
if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:#"Let's just quickly check that you are the device owner."
reply:^(BOOL success, NSError *error) {
dispatch_async (dispatch_get_main_queue(), ^{
if (error) {
// Error occurred
} else if (success) {
// Device owner, success!
} else {
// Not device owner
}
});
}];
}
But I want to know when the user tapped 'Enter password' which is LAErrorUserFallback. However I just want to know how to compare the error variable I have there with the LAErrorUserFallback to see the outcome error.
I have tried this:
if (error) {
if (error == LAErrorUserFallback) {
// User tapped 'Enter password'
}
}
but obviously these are not the same type.
Any help?
According to the docs, that's the error code.
So try something like error.code == LAErrorUserFallback.

Resources