Skip to content

Commit d1f7a29

Browse files
committed
Fixes nil appId handling, for wrapper SDKs
* Fixes firing of the handleNotificationAction event for some wrapper SDKs - Cordova, Unity, and possibly others * When a nil appId is passed to OneSignal.initWithLaunchOptions a cached value will be used - Needed as the SDK needs to init on launch of the process but the appId is passed in from the wrapper runtime
1 parent d81d70f commit d1f7a29

File tree

2 files changed

+97
-34
lines changed

2 files changed

+97
-34
lines changed

iOS_SDK/OneSignalSDK/Source/OneSignal.m

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
#define ERROR_PUSH_CAPABLILITY_DISABLED -13
7272
#define ERROR_PUSH_DELEGATE_NEVER_FIRED -14
7373
#define ERROR_PUSH_SIMULATOR_NOT_SUPPORTED -15
74-
#define ERROR_PUSH_UNKNOWN_APNS_ERROR -16
74+
#define ERROR_PUSH_UNKNOWN_APNS_ERROR -16
7575
#define ERROR_PUSH_OTHER_3000_ERROR -17
7676
#define ERROR_PUSH_NEVER_PROMPTED -18
7777
#define ERROR_PUSH_PROMPT_NEVER_ANSWERED -19
@@ -329,47 +329,19 @@ + (id)initWithLaunchOptions:(NSDictionary*)launchOptions appId:(NSString*)appId
329329
// Ensure a 2nd call can be made later with the appId from the developer's code.
330330
+ (id)initWithLaunchOptions:(NSDictionary*)launchOptions appId:(NSString*)appId handleNotificationReceived:(OSHandleNotificationReceivedBlock)receivedCallback handleNotificationAction:(OSHandleNotificationActionBlock)actionCallback settings:(NSDictionary*)settings {
331331

332-
if (![[NSUUID alloc] initWithUUIDString:appId]) {
333-
onesignal_Log(ONE_S_LL_FATAL, @"OneSignal AppId format is invalid.\nExample: 'b2f7f966-d8cc-11eg-bed1-df8f05be55ba'\n");
334-
return self;
335-
}
332+
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
336333

337-
if ([@"b2f7f966-d8cc-11eg-bed1-df8f05be55ba" isEqualToString:appId] || [@"5eb5a37e-b458-11e3-ac11-000c2940e62c" isEqualToString:appId])
338-
onesignal_Log(ONE_S_LL_WARN, @"OneSignal Example AppID detected, please update to your app's id found on OneSignal.com");
334+
bool success = [self initAppId:appId withUserDefaults:userDefaults withSettings:settings];
335+
336+
if (!success)
337+
return self;
339338

340339
if (mShareLocation)
341340
[OneSignalLocation getLocation:false];
342341

343342
if (self) {
344-
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
345-
346343
[OneSignalHelper notificationBlocks: receivedCallback : actionCallback];
347344

348-
if (appId)
349-
app_id = appId;
350-
else {
351-
// Read from .plist if not passed in with this method call.
352-
app_id = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"OneSignal_APPID"];
353-
if (app_id == nil)
354-
app_id = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"GameThrive_APPID"];
355-
}
356-
357-
// Handle changes to the app id. This might happen on a developer's device when testing.
358-
if (app_id == nil)
359-
app_id = [userDefaults stringForKey:@"GT_APP_ID"];
360-
else if (![app_id isEqualToString:[userDefaults stringForKey:@"GT_APP_ID"]]) {
361-
// Will run the first time OneSignal is initialized or if the dev changes the app_id.
362-
[userDefaults setObject:app_id forKey:@"GT_APP_ID"];
363-
[userDefaults setObject:nil forKey:@"GT_PLAYER_ID"];
364-
[userDefaults synchronize];
365-
}
366-
367-
if (!app_id) {
368-
if (![settings[kOSSettingsKeyInOmitNoAppIdLogging] boolValue])
369-
onesignal_Log(ONE_S_LL_FATAL, @"OneSignal AppId never set!");
370-
return self;
371-
}
372-
373345
if ([OneSignalHelper isIOSVersionGreaterOrEqual:8])
374346
registeredWithApple = self.currentPermissionState.accepted;
375347
else
@@ -447,6 +419,40 @@ + (id)initWithLaunchOptions:(NSDictionary*)launchOptions appId:(NSString*)appId
447419
return self;
448420
}
449421

422+
+(bool)initAppId:(NSString*)appId withUserDefaults:(NSUserDefaults*)userDefaults withSettings:(NSDictionary*)settings {
423+
if (appId)
424+
app_id = appId;
425+
else {
426+
// Read from .plist if not passed in with this method call.
427+
app_id = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"OneSignal_APPID"];
428+
if (app_id == nil)
429+
app_id = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"GameThrive_APPID"];
430+
}
431+
432+
if (!app_id) {
433+
if (![settings[kOSSettingsKeyInOmitNoAppIdLogging] boolValue])
434+
onesignal_Log(ONE_S_LL_FATAL, @"OneSignal AppId never set!");
435+
app_id = [userDefaults stringForKey:@"GT_APP_ID"];
436+
}
437+
else if (![app_id isEqualToString:[userDefaults stringForKey:@"GT_APP_ID"]]) {
438+
// Handle changes to the app id. This might happen on a developer's device when testing
439+
// Will also run the first time OneSignal is initialized
440+
[userDefaults setObject:app_id forKey:@"GT_APP_ID"];
441+
[userDefaults setObject:nil forKey:@"GT_PLAYER_ID"];
442+
[userDefaults synchronize];
443+
}
444+
445+
if (!app_id || ![[NSUUID alloc] initWithUUIDString:app_id]) {
446+
onesignal_Log(ONE_S_LL_FATAL, @"OneSignal AppId format is invalid.\nExample: 'b2f7f966-d8cc-11e4-bed1-df8f05be55ba'\n");
447+
return false;
448+
}
449+
450+
if ([@"b2f7f966-d8cc-11e4-bed1-df8f05be55ba" isEqualToString:appId] || [@"5eb5a37e-b458-11e3-ac11-000c2940e62c" isEqualToString:appId])
451+
onesignal_Log(ONE_S_LL_WARN, @"OneSignal Example AppID detected, please update to your app's id found on OneSignal.com");
452+
453+
return true;
454+
}
455+
450456
+ (void)setLogLevel:(ONE_S_LOG_LEVEL)nsLogLevel visualLevel:(ONE_S_LOG_LEVEL)visualLogLevel {
451457
NSLog(@"ONESIGNAL - Setting log level: %d", (int)nsLogLevel);
452458
_nsLogLevel = nsLogLevel; _visualLogLevel = visualLogLevel;

iOS_SDK/OneSignalSDK/UnitTests/UnitTests.m

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,26 @@ + (void)runPendingSelectors {
156156

157157

158158

159+
160+
@interface NSUUIDOverrider : NSObject
161+
@end
162+
163+
@implementation NSUUIDOverrider
164+
+ (void)load {
165+
// Swizzling initWithUUIDString: doesn't seem possible
166+
injectToProperClass(@selector(overrideInitWithUUIDString:), @selector(initWithUUIDString:), @[], [NSUUIDOverrider class], [NSUUID class]);
167+
}
168+
169+
- (id)overrideInitWithUUIDString:(NSString*)string {
170+
// Mimic iOS 11 logic
171+
if (!string)
172+
return nil;
173+
174+
return [self overrideInitWithUUIDString:string];
175+
}
176+
@end
177+
178+
159179
@interface NSUserDefaultsOverrider : NSObject
160180
@end
161181

@@ -275,6 +295,15 @@ + (void)sizzleBundleIdentifier {
275295
- (NSString*)overrideBundleIdentifier {
276296
return @"com.onesignal.unittest";
277297
}
298+
299+
- (NSURL*)overrideBundleURL {
300+
NSURL* url = [NSURL URLWithString:@"file:///Users/hiro/Library/Developer/CoreSimulator/Devices/63A47DBE-D6F7-4BCF-82C4-5285C91CB22C/data/Containers/Bundle/Application/D5FDD051-990C-426E-89B1-E4C51429D29D/OneSignalDevApp.app/"];
301+
302+
// NSURL* url = [self overrideBundleURL];
303+
NSLog(@"url: %@", url);
304+
305+
return url;
306+
}
278307

279308
- (nullable id)overrideObjectForInfoDictionaryKey:(NSString*)key {
280309
return nsbundleDictionary[key];
@@ -1663,6 +1692,34 @@ - (void)testNotificationOpen {
16631692
XCTAssertEqual(networkRequestCount, 2);
16641693
}
16651694

1695+
1696+
1697+
// Wrapper SDKs may not have the app_id available on cold starts.
1698+
// Open event should still fire however so the event is not missed.
1699+
- (void)testNotificationOpenOn2ndColdStartWithoutAppId {
1700+
[self initOneSignal];
1701+
[self runBackgroundThreads];
1702+
1703+
[self clearStateForAppRestart];
1704+
1705+
__block BOOL openedWasFire = false;
1706+
[OneSignal initWithLaunchOptions:nil appId:nil handleNotificationAction:^(OSNotificationOpenedResult *result) {
1707+
openedWasFire = true;
1708+
}];
1709+
[self runBackgroundThreads];
1710+
1711+
id notifResponse = [self createBasiciOSNotificationResponse];
1712+
UNUserNotificationCenter *notifCenter = [UNUserNotificationCenter currentNotificationCenter];
1713+
id notifCenterDelegate = notifCenter.delegate;
1714+
// UNUserNotificationCenterDelegate method iOS 10 calls directly when a notification is opened.
1715+
[notifCenterDelegate userNotificationCenter:notifCenter didReceiveNotificationResponse:notifResponse withCompletionHandler:^() {}];
1716+
1717+
XCTAssertTrue(openedWasFire);
1718+
}
1719+
1720+
1721+
1722+
16661723
// Testing iOS 10 - old pre-2.4.0 button fromat - with original aps payload format
16671724
- (void)testNotificationOpenFromButtonPress {
16681725
__block BOOL openedWasFire = false;

0 commit comments

Comments
 (0)