I have an app which uses local notifications. In iOS 7 everything works fine, but in iOS 8 the app needs to ask for user permission to display notifications. To ask for perm
In case you still want to compile against older SDKs or have a special reason to do so, you may try calling the whole stuff dynamically:
#ifdef __IPHONE_8_0
#define USING_IOS8_SDK
#else // iOS <8 SDK compatibility definitions
#define UIUserNotificationTypeNone (0)
#define UIUserNotificationTypeBadge (1 << 0)
#define UIUserNotificationTypeSound (1 << 1)
#define UIUserNotificationTypeAlert (1 << 2)
#endif
...
if ([_sharedApplication respondsToSelector:NSSelectorFromString(@"registerUserNotificationSettings:")])
{
NSUInteger settingsParam = (UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound);
id categoriesParam = nil;
#ifdef USING_IOS8_SDK
// Perform direct call when using iOS 8 SDK
[_sharedApplication registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:settingsParam categories:categoriesParam]];
#else
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
// Do the dynamic stuff
// Get UIUserNotificationSettings class reference
Class settings = NSClassFromString(@"UIUserNotificationSettings");
if (settings) {
// Prepare class selector
SEL sel = NSSelectorFromString(@"settingsForTypes:categories:");
// Obtain a method signature of selector on UIUserNotificationSettings class
NSMethodSignature *signature = [settings methodSignatureForSelector:sel];
// Create an invocation on a signature -- must be used because of primitive (enum) arguments on selector
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.selector = sel;
invocation.target = settings;
// Set arguments
[invocation setArgument:&settingsParam atIndex:2];
[invocation setArgument:&categoriesParam atIndex:3];
// Obtain an instance by firing an invocation
NSObject *settingsInstance;
[invocation invoke];
[invocation getReturnValue:&settingsInstance];
// Retain an instance so it can live after quitting method and prevent crash :-)
CFRetain((__bridge CFTypeRef)(settingsInstance));
// Finally call the desired method with proper settings
if (settingsInstance)
[_sharedApplication performSelector:NSSelectorFromString(@"registerUserNotificationSettings:") withObject:settingsInstance];
}
#pragma clang diagnostic pop
#endif
}
This should perfectly compile on iOS 7 SDK and work (effectively) on iOS 8 devices, ignored on older ones.
Migrating your project to iOS 8 SDK is another solution, thought, but there are still options.