0

Hi I have an app that I have set up with push notifications and they are working. My last step is that when a user opens the app and is asked if they want to allow push notification, I want to set a pointer from that user to the installation id associated with that phone. I can do that using this

 PFInstallation *currentInstalation = [PFInstallation currentInstallation];
 NSString *installationObjectId = currentInstalation.objectId;
[currentUser setObject:installationObjectId forKey:@"installationString"];
[currentUser setObject:currentInstalation forKey:@"installation"];

Here is a pic of part of my user class to clarify

enter image description here

But I don't want to make this save every time the user opens the app, I just want to do it the once if it has not been set yet. So I was going to use this if statement to check if it had been set yet

if (![currentUser[@"installationString"] isEqual:installationObjectId]) {
//save it here
}

But the problem comes if the user taps, "don't allow push notifications" because then there is no installation object set, so the installation object for that phone/ user is null and the above if statement gives the error below

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: 'Can't use nil for keys or values on PFObject. Use NSNull for values.'

And the app fails. Is there another/ better way to check if the pointer has been set, so that if the user taps "don't allow" and then reopens the app it won't quit out.

Thanks for the help in advance I really appreciate it!!!

EDIT

APP DELAGTE CODE

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
                                                    UIUserNotificationTypeBadge |
                                                    UIUserNotificationTypeSound);
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
                                                                             categories:nil];
    [application registerUserNotificationSettings:settings];
    [application registerForRemoteNotifications];
} else {
    // Register for Push Notifications before iOS 8
    [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                     UIRemoteNotificationTypeAlert |
                                                     UIRemoteNotificationTypeSound)];
}
- (void)application:(UIApplication *)application 

didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    // Store the deviceToken in the current installation and save it to Parse.
    PFInstallation *currentInstallation = [PFInstallation currentInstallation];
    [currentInstallation setDeviceTokenFromData:deviceToken];
    [currentInstallation saveInBackground];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    [PFPush handlePush:userInfo];
}

And I have it set this way because I have a cloud function that send pushes to user and and get a pointer from the user to the installation id to send the push, maybe I could consider flipping that?

And if the user clicks don't allow. Doesn't Parse.com not save an installation id for that device?

Thanks

Lukesivi
  • 2,206
  • 4
  • 25
  • 43
  • I don't know if the reason you're doing it this way is specific to your app, but I usually add a pointer to the _User table in the Installation table, so the device itself is linked to a user. I haven't had any problems with selecting "don't allow" and then opening the app. I just check the column in the Installation table to see if its null, and if it is, then set it equal to the current user. Can you post the code in your AppDelegate that deals with notifications? – Jacob Oct 01 '14 at 21:03
  • What method in the AppDelegate are the first few lines of code in? – Jacob Oct 01 '14 at 23:43
  • `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions` –  Oct 01 '14 at 23:51
  • I believe if you flip where the pointers are (put one in the installation table instead of the user table), your problem will be solved. I may be misunderstanding the problem, though. – Jacob Oct 02 '14 at 00:20

2 Answers2

1

This should help PFInstallation *currentInstalation = [PFInstallation currentInstallation]; NSString *installationObjectId = currentInstalation.objectId; [currentUser setObject:installationObjectId forKey:@"installationString"]; [currentUser setObject:currentInstalation forKey:@"installation"];

iqueqiorio
  • 1,149
  • 2
  • 35
  • 78
0

SWIFT:

   var newUser = PFUser()
   var currentInstallation = PFInstallation.currentInstallation()
   let installationObjectId: NSString = currentInstallation.installationId

        newUser.setObject(installationObjectId, forKey: "installationString")
        newUser.setObject(currentInstallation, forKey: "installation")
        newUser.saveInBackgroundWithBlock { (success, error) -> Void in
            if error == nil {
              print("success")
            } else {

                print(error)
            }
        }
Lukesivi
  • 2,206
  • 4
  • 25
  • 43