1
votes

my app is supposed to show location-aware ads via iBeacon ranging. There is no problem with that: the app awakes in the background when 'sees' certain beacons and schedules local notifications that are delivered right in time.

The problem is that the local notification delivered to the locked screen doesn't light up the screen or even play any sound or vibrate -- which is a catastrophe for marketing team.

Sounds being played normally when notification is delivered to the foreground but missed when delivered to the locked screen.

Here is my code for scheduling local notification for UNUserNotificationCenter:

- (void)scheduleLocalNotificationImageWithTitle:(NSString*)title andBody:(NSString*)body andImagePath:(NSString*)imagePath{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
UNNotificationAction *deleteAction = [UNNotificationAction actionWithIdentifier:@"Close"
                                                                          title:@"Close" options:UNNotificationActionOptionDestructive];

UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"NOT_CategoryImage"
                                                                          actions:@[deleteAction] intentIdentifiers:@[]
                                                                          options:UNNotificationCategoryOptionNone];
NSSet *categories = [NSSet setWithObject:category];

[center setNotificationCategories:categories];

UNNotificationAttachment *imageAttachment = [UNNotificationAttachment attachmentWithIdentifier:@"SaleNOTIF_Image" URL:[NSURL fileURLWithPath:imagePath] options:nil error:nil];

UNMutableNotificationContent *content = [UNMutableNotificationContent new];
content.title = title;
content.body = body;
content.sound = [UNNotificationSound defaultSound];
content.attachments = @[imageAttachment];

UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.1 repeats:NO];

NSString *identifier = @"NotificationImage";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];

[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
    if (error != nil) {
        NSLog(@"Something went wrong: %@",error);
    }
}];
}

And code for UNUserNotificationCenter in didFinishLaunching:

    UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
    if( !error ){

    }
}];
[[UIApplication sharedApplication] registerForRemoteNotifications];


UNNotificationCategory* generalCategory = [UNNotificationCategory
                                           categoryWithIdentifier:@"GENERAL"
                                           actions:@[]
                                           intentIdentifiers:@[]
                                           options:UNNotificationCategoryOptionAllowInCarPlay];



// Register the notification categories.
[center setNotificationCategories:[NSSet setWithObjects:generalCategory, nil]];

I also have center willPresentNotification method but as far as I know it's only useful for foreground.

-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{    
CLS_LOG(@"Userinfo %@", notification.request.content.body);

completionHandler(UNNotificationPresentationOptionSound + UNNotificationPresentationOptionAlert);
}

Any ideas what am I missing?

1

1 Answers

4
votes

Okay I finally found out what it was using this thread on Apple public discussions.

The story itself is hilarious: I built my project in the office and the app remained silent. Then I went back home and continued working with my MacBook Pro and - voila! - everything worked. I locked my screen and notifications popped and sounded right through as they are supposed to. The other day I ran to my office with my MacBook and built the same code but nothing changed: my app just kept silent as it did two days ago. I've dug up everything including proxies and GPS and found nothing, BECAUSE...

It turns out the code was OK and the issue itself lies somewhere in the system. So the key to the solution is just to prevent your (and your users') Apple Watch from repeating notifications of your app (simply from Watch app). Because if it repeats it makes iPhone silent.

This was probably made to prevent notifications from firing everything up with sounds and vibrations and only let you know that smth exciting happened using the closest device (right now watch is closer than anything if it's on your wrist). So that's why everything worked when I was at home: I simply wasn't wearing Watch so it didn't have to repeat notifications and so wasn't blocking them.

I just hope this can someone else a ton of time while working with notifications on iOS 11. Just keep in mind there's always WATCH.