Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>A bit late, but it might help someone.</p> <p>I faced a similar situation in a project of mine:</p> <h1>The problem</h1> <ol> <li>First run gets the device token </li> <li>user logs in and the app registers the device token with the server</li> <li>user uninstalls the app without logging out hence the server still thinks it's active</li> <li>user reinstalls app, and still receives push notifications even though they're not logged in yet</li> </ol> <p>In my app I register and request for the device token in the app delegate:</p> <pre><code>- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ .. [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; .. } </code></pre> <p>And once the reply is received from Apple:</p> <pre><code>- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)token{ //Get trimmed device token NSString *deviceToken = [[token description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"&lt;&gt;"]]; deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""]; //Store the device token in the user defaults NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setObject:deviceToken forKey:@"dToken"]; [userDefaults synchronize]; } </code></pre> <p>This is more or less the typical way I've seen it done.</p> <p>Now when the user logs in, the device token is sent to the server and registered from the main view controller of the user content area. The device token is retrieved by accessing the user defaults from within that view controller. The problem however is if the user never logs in to the user content area, the notifications will still persist because the device was never unregistered with the server as a result of the previous uninstall while still logged in.</p> <h1>The Solution</h1> <p>There are a few approaches to solving this problem as mentioned in other answers. However I didn't want to modify my server and the main structure of registering devices there, which goes something like:</p> <ul> <li>When the user first logs in: authenticate the user and register the passed device token at the same time.</li> <li>When the user logs out: unregister the device token to that user.</li> <li>Whenever a device token exists in the DB: deactivate it for all users except for the user currently logging in.</li> </ul> <p>Seeing that the user content area must have the device token to log in the user, I start by requesting the device token in <strong>didFinishLaunchingWithOptions</strong> as I did before.</p> <p>Now when a reply is received in <strong>didRegisterForRemoteNotificationsWithDeviceToken</strong> I do the following:</p> <pre><code>- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)token{ //Get trimmed device token NSString *deviceToken = [[token description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"&lt;&gt;"]]; deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""]; //Store the device token in the user defaults NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setObject:deviceToken forKey:@"dToken"]; [userDefaults synchronize]; //If not logged in yet, unregister for notifications if(![[NSUserDefaults standardUserDefaults] objectForKey:@"loggedIn"]) [[UIApplication sharedApplication] unregisterForRemoteNotifications]; } </code></pre> <p>I check if the user content view controller has not been reached yet, i.e. the user never logged in, and disable the notifications.</p> <p>In the user content view controller I do the following:</p> <pre><code>- (void)viewDidLoad{ .. //Set logged-in so the notifications continue to be received if(![[NSUserDefaults standardUserDefaults] objectForKey:@"loggedIn"]){ [[NSUserDefaults standardUserDefaults] setValue:@"done" forKey:@"loggedIn"]; [[NSUserDefaults standardUserDefaults] synchronize]; //Register for notifications (again) [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; } //Send user authentication and device token (retrieved from the user defaults) to server .. } </code></pre> <p>Now whenever the user first logs in the device token is sent to the server and registered without any delays because it has already been retrieved from Apple. The notifications are also disabled until the user logs in and therefore the main problem is solved.</p> <p>This approach insures that the user content area view controller is never loaded without the device token saved in the user defaults and therefore allows me to continue using the same method of authenticating the user and passing the device token at once.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload