@@ -117,21 +117,16 @@ @implementation OneSignal
117117OSFailureBlock tokenUpdateFailureBlock;
118118
119119int mLastNotificationTypes = -1 ;
120- int mSubscriptionStatus = -1 ;
120+ static int mSubscriptionStatus = -1 ;
121121
122122OSIdsAvailableBlock idsAvailableBlockWhenReady;
123123BOOL disableBadgeClearing = NO ;
124124BOOL mSubscriptionSet;
125125BOOL mShareLocation = YES ;
126126
127- + (void ) clearStatics {
128- waitingForApnsResponse = false ;
129- registeredWithApple = NO ;
130-
131- mLastNotificationTypes = -1 ;
132- mSubscriptionStatus = -1 ;
127+ + (void ) setMSubscriptionStatus : (NSNumber *)status {
128+ mSubscriptionStatus = [status intValue ];
133129}
134-
135130
136131+ (NSString *)app_id {
137132 return app_id;
@@ -342,20 +337,26 @@ void onesignal_Log(ONE_S_LOG_LEVEL logLevel, NSString* message) {
342337
343338
344339// iOS 8+, only tries to register for an APNs token if one is true:
345- // - UIBackground > remote-notification" modes are on
346- // - The user already accepted notification permssion
347340+ (BOOL )registerForAPNsToken {
348341 if (waitingForApnsResponse)
349342 return true ;
350343
351344 id backgroundModes = [[NSBundle mainBundle ] objectForInfoDictionaryKey: @" UIBackgroundModes" ];
352345 backgroundModesEnabled = (backgroundModes && [backgroundModes containsObject: @" remote-notification" ]);
353346
347+ // Only try to register for a pushToken if:
348+ // - The user accepted notifications
349+ // - Background Modes > Remote Notifications are enabled in Xcode
354350 if (![self accpetedNotificationPermission ] && !backgroundModesEnabled)
355351 return false ;
356352
353+ // Don't attempt to register again if the was non-recoverable error.
354+ if (mSubscriptionStatus < -9 )
355+ return false ;
356+
357357 waitingForApnsResponse = true ;
358358 [[UIApplication sharedApplication ] registerForRemoteNotifications ];
359+
359360 return true ;
360361}
361362
@@ -393,11 +394,25 @@ + (void)registerForPushNotifications {
393394
394395// Block not assigned if userID nil and there is a device token
395396+ (void )IdsAvailable : (OSIdsAvailableBlock)idsAvailableBlock {
396- if (mUserId)
397- idsAvailableBlock (mUserId, [self getUsableDeviceToken ]);
397+ idsAvailableBlockWhenReady = idsAvailableBlock;
398+ [self fireIdsAvailableCallback ];
399+ }
400+
401+ + (void ) fireIdsAvailableCallback {
402+ if (!idsAvailableBlockWhenReady)
403+ return ;
404+ if (!mUserId)
405+ return ;
398406
399- if (!mUserId || ![self getUsableDeviceToken ])
400- idsAvailableBlockWhenReady = idsAvailableBlock;
407+ // Ensure we are on the main thread incase app developer updates UI from the callback.
408+ dispatch_async (dispatch_get_main_queue (), ^{
409+ id pushToken = [self getUsableDeviceToken ];
410+ if (!idsAvailableBlockWhenReady)
411+ return ;
412+ idsAvailableBlockWhenReady (mUserId, pushToken);
413+ if (pushToken)
414+ idsAvailableBlockWhenReady = nil ;
415+ });
401416}
402417
403418+ (void )sendTagsWithJsonString : (NSString *)jsonString {
@@ -626,20 +641,20 @@ + (void) handleDidFailRegisterForRemoteNotification:(NSError*)err {
626641 if (err.code == 3000 ) {
627642 if ([((NSString *)[err.userInfo objectForKey: NSLocalizedDescriptionKey ]) rangeOfString: @" no valid 'aps-environment'" ].location != NSNotFound ) {
628643 // User did not enable push notification capability
629- [OneSignal setSubscriptionStatus : ERROR_PUSH_CAPABLILITY_DISABLED];
644+ [OneSignal setSubscriptionErrorStatus : ERROR_PUSH_CAPABLILITY_DISABLED];
630645 [OneSignal onesignal_Log: ONE_S_LL_ERROR message: @" ERROR! 'Push Notification' capability not turned on! Enable it in Xcode under 'Project Target' -> Capability." ];
631646 }
632647 else {
633- [OneSignal setSubscriptionStatus : ERROR_PUSH_OTHER_3000_ERROR];
648+ [OneSignal setSubscriptionErrorStatus : ERROR_PUSH_OTHER_3000_ERROR];
634649 [OneSignal onesignal_Log: ONE_S_LL_ERROR message: [NSString stringWithFormat: @" ERROR! Unkown 3000 error returned from APNs when getting a push token: %@ " , err]];
635650 }
636651 }
637652 else if (err.code == 3010 ) {
638- [OneSignal setSubscriptionStatus : ERROR_PUSH_SIMULATOR_NOT_SUPPORTED];
653+ [OneSignal setSubscriptionErrorStatus : ERROR_PUSH_SIMULATOR_NOT_SUPPORTED];
639654 [OneSignal onesignal_Log: ONE_S_LL_ERROR message: [NSString stringWithFormat: @" Error! iOS Simulator does not support push! Please test on a real iOS device. Error: %@ " , err]];
640655 }
641656 else {
642- [OneSignal setSubscriptionStatus : ERROR_PUSH_UNKOWN_APNS_ERROR];
657+ [OneSignal setSubscriptionErrorStatus : ERROR_PUSH_UNKOWN_APNS_ERROR];
643658 [OneSignal onesignal_Log: ONE_S_LL_ERROR message: [NSString stringWithFormat: @" Error registering for Apple push notifications! Error: %@ " , err]];
644659 }
645660}
@@ -704,13 +719,7 @@ + (void)updateDeviceToken:(NSString*)deviceToken onSuccess:(OSResultSuccessBlock
704719
705720 [OneSignalHelper enqueueRequest: request onSuccess: successBlock onFailure: failureBlock];
706721
707- if (idsAvailableBlockWhenReady) {
708- if ([self getUsableDeviceToken ]) {
709- idsAvailableBlockWhenReady (mUserId, [self getUsableDeviceToken ]);
710- idsAvailableBlockWhenReady = nil ;
711- }
712- }
713-
722+ [self fireIdsAvailableCallback ];
714723}
715724
716725// Set to yes whenever a high priority registration fails ... need to make the next one a high priority to disregard the timer delay
@@ -861,11 +870,7 @@ + (void)registerUser {
861870 emailToSet = nil ;
862871 }
863872
864- if (idsAvailableBlockWhenReady) {
865- idsAvailableBlockWhenReady (mUserId, [self getUsableDeviceToken ]);
866- if (mDeviceToken)
867- idsAvailableBlockWhenReady = nil ;
868- }
873+ [self fireIdsAvailableCallback ];
869874
870875 [self sendNotificationTypesUpdate ];
871876 }
@@ -900,8 +905,8 @@ + (BOOL) sendNotificationTypesUpdate {
900905 // User changed notification settings for the app.
901906 if ([self getNotificationTypes ] != -1 && mUserId && mLastNotificationTypes != [self getNotificationTypes ]) {
902907 if (mDeviceToken == nil ) {
903- [self registerForAPNsToken ];
904- return true ;
908+ if ( [self registerForAPNsToken ])
909+ return true ;
905910 }
906911
907912 mLastNotificationTypes = [self getNotificationTypes ];
@@ -915,17 +920,15 @@ + (BOOL) sendNotificationTypesUpdate {
915920
916921 [OneSignalHelper enqueueRequest: request onSuccess: nil onFailure: nil ];
917922
918- if ([self getUsableDeviceToken ] && idsAvailableBlockWhenReady) {
919- idsAvailableBlockWhenReady (mUserId, [self getUsableDeviceToken ]);
920- idsAvailableBlockWhenReady = nil ;
921- }
923+ if ([self getUsableDeviceToken ])
924+ [self fireIdsAvailableCallback ];
922925
923926 return true ;
924927 }
925928
926929 return false ;
927930}
928-
931+
929932+ (void )sendPurchases : (NSArray *)purchases {
930933 if (mUserId == nil )
931934 return ;
@@ -1162,9 +1165,12 @@ + (int) getNotificationTypes {
11621165 return 0 ;
11631166}
11641167
1165- + (void )setSubscriptionStatus : (int )errorType {
1168+ + (void )setSubscriptionErrorStatus : (int )errorType {
11661169 mSubscriptionStatus = errorType;
1167- [self sendNotificationTypesUpdate ];
1170+ if (mUserId)
1171+ [self sendNotificationTypesUpdate ];
1172+ else
1173+ [self registerUser ];
11681174}
11691175
11701176+ (void )userAnsweredNotificationPrompt : (void (^)(OSSubcscriptionStatus *anwsered))completionHandler {
@@ -1218,8 +1224,8 @@ + (void) updateNotificationTypes:(int)notificationTypes {
12181224 else if (mDeviceToken)
12191225 [self sendNotificationTypesUpdate ];
12201226
1221- if (idsAvailableBlockWhenReady && mUserId && [self getUsableDeviceToken ])
1222- idsAvailableBlockWhenReady (mUserId, [self getUsableDeviceToken ]) ;
1227+ if ([self getUsableDeviceToken ])
1228+ [self fireIdsAvailableCallback ] ;
12231229}
12241230
12251231+ (void )didRegisterForRemoteNotifications : (UIApplication*)app deviceToken : (NSData *)inDeviceToken {
0 commit comments