Without knowing much about Urban Airship I can offer a guess.
takeOff
ensures that the actual implementation provided in executeUnsafeTakeoff
only happens once. It makes sure that the current thread is the main thread and then ensures that it only happens once.
Therefore getting an executeUnsafeTakeoff
error really only tells you that something went wrong, such as if the configfailed to
validate` (see below).
You need to make sure that the app can receive push notifications, as you mentioned.
Here is takeOff
:
+ (void)takeOff {
[UAirship takeOff:[UAConfig defaultConfig]];
}
+ (void)takeOff:(UAConfig *)config {
// takeOff needs to be run on the main thread
if (![[NSThread currentThread] isMainThread]) {
NSException *mainThreadException = [NSException exceptionWithName:UAirshipTakeOffBackgroundThreadException
reason:@"UAirship takeOff must be called on the main thread."
userInfo:nil];
[mainThreadException raise];
}
dispatch_once(&takeOffPred_, ^{
[UAirship executeUnsafeTakeOff:config];
});
}
Here is executeUnsafeTakeoff
:
/*
* This is an unsafe version of takeOff - use takeOff: instead for dispatch_once
*/
+ (void)executeUnsafeTakeOff:(UAConfig *)config {
// Airships only take off once!
if (_sharedAirship) {
return;
}
[UAirship setLogLevel:config.logLevel];
_sharedAirship = [[UAirship alloc] init];
_sharedAirship.config = config;
// Ensure that app credentials have been passed in
if (![config validate]) {
UA_LERR(@"The AirshipConfig.plist file is missing and no application credentials were specified at runtime.");
// Bail now. Don't continue the takeOff sequence.
return;
}
UA_LINFO(@"App Key: %@", _sharedAirship.config.appKey);
UA_LINFO(@"App Secret: %@", _sharedAirship.config.appSecret);
UA_LINFO(@"Server: %@", _sharedAirship.config.deviceAPIURL);
if (config.automaticSetupEnabled) {
_sharedAirship.appDelegate = [[UAAppDelegateProxy alloc ]init];
//swap pointers with the initial app delegate
@synchronized ([UIApplication sharedApplication]) {
_sharedAirship.appDelegate.originalAppDelegate = [UIApplication sharedApplication].delegate;
_sharedAirship.appDelegate.airshipAppDelegate = [[UAAppDelegate alloc] init];
[UIApplication sharedApplication].delegate = _sharedAirship.appDelegate;
}
}
// Build a custom user agent with the app key and name
[_sharedAirship configureUserAgent];
// Set up analytics
_sharedAirship.analytics = [[UAAnalytics alloc] initWithConfig:_sharedAirship.config];
[_sharedAirship.analytics delayNextSend:UAAnalyticsFirstBatchUploadInterval];
/*
* Handle Debug Options
*/
//For testing, set this value in AirshipConfig to clear out
//the keychain credentials, as they will otherwise be persisted
//even when the application is uninstalled.
if (config.clearKeychain) {
UA_LDEBUG(@"Deleting the keychain credentials");
[UAKeychainUtils deleteKeychainValue:_sharedAirship.config.appKey];
UA_LDEBUG(@"Deleting the UA device ID");
[UAKeychainUtils deleteKeychainValue:kUAKeychainDeviceIDKey];
}
if (!config.inProduction) {
[_sharedAirship validate];
}
if (config.cacheDiskSizeInMB > 0) {
UA_LINFO("Registering UAURLProtocol");
[NSURLProtocol registerClass:[UAURLProtocol class]];
}
// The singleton is now ready for use!
_sharedAirship.ready = true;
//create/setup user (begin listening for device token changes)
[[UAUser defaultUser] initializeUser];
}