Search code examples
iosobjective-cxcodeuilocalnotification

UILocalNotification not sending notifications


I have code for setting multiple UILocalNotifications for the next few weeks. In my didFinishLaunchingWithOptions I have code that asks for permission to send notifications and then I have my code to setup my notifications.

But still, the code returns an error:

Haven't received permission from the user to display alerts

I think it is trying to run the notification code before the user can approve permission.

How do I make my notification code run only if the user says OK to receiving notifications?

Here is my code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]){
        [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
    }
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if ([defaults objectForKey:@"FirstTimeBool"]==nil) {
        [defaults setObject:@"YES" forKey:@"FirstTimeBool"];
        NSDate *today = [NSDate date];
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"MMMM dd, yyyy"];

        NSString* path = [[NSBundle mainBundle] pathForResource:@"example"
                                                         ofType:@"txt"];
        NSString* content = [NSString stringWithContentsOfFile:path
                                                      encoding:NSUTF8StringEncoding
                                                         error:NULL];
        NSArray* allLinedStrings = [content componentsSeparatedByCharactersInSet:
                                    [NSCharacterSet newlineCharacterSet]];
        for (int i = 0; i < allLinedStrings.count; i++) {
            NSString* strsInOneLine = [allLinedStrings objectAtIndex:i];
            NSArray* singleStrs = [strsInOneLine componentsSeparatedByCharactersInSet:
                                   [NSCharacterSet characterSetWithCharactersInString:@";"]];
            NSString *date = [singleStrs objectAtIndex:0];
            NSDate *eventDate = [dateFormatter dateFromString:date];
            if ([today compare:eventDate] == NSOrderedAscending) {
                for (int j = 1; j < singleStrs.count; j+=2) {
                    UILocalNotification *notification = [[UILocalNotification alloc]init];
                    notification.fireDate = [NSDate dateWithTimeInterval:60*60*-24 sinceDate:eventDate];
                    notification.alertBody = [singleStrs objectAtIndex:j+1];
                    notification.alertTitle = [singleStrs objectAtIndex:j];
                    notification.timeZone = [NSTimeZone defaultTimeZone];
                    [[UIApplication sharedApplication]scheduleLocalNotification:notification];
                }
            }
        }
    }

    // Override point for customization after application launch.
    return YES;
}

Solution

  • For iOS 8 and higher you should use this AppDelegate function which is called when user has accepted notifications:

    - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings 
    

    Before iOS 8 you should use this:

    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    

    More information can be found here: About Local Notifications and Remote Notification.