9

There are multiple examples how you should set up your project to add rich notifications which use 'media attachments' technology to show images. I've read most of them but something I missed, because my project does not display any rich notifications with this payload (tested with APNS-Tool and Boodle):

{
    "aps":{
        "alert":{
            "title": "Rich test",
            "body": "Dancing Banana"
        },
        "mutable-content": 1
    }
}

The notification is visible, but on 3D Touch, there are no additional infos displayed (like the image or the modified title). The notification extension breakpoints and NSLog messages are also not working.

Here is my demo project: https://github.com/gklka/RichTest

What I've done:

  1. Created a new project
  2. implemented iOS-style authorization:
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError * _Nullable error) {

        if (granted) {
            NSLog(@"Granted");

            [[UIApplication sharedApplication] registerForRemoteNotifications];

        } else {
            NSLog(@"Error registering: %@", error);
        }

    }];
  1. added debug to AppDelegate:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSLog(@"Token: %@", deviceToken);
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"Error: %@", error);
}
  1. Added a new target to the project: Notification Service Extension:

Add new target

  1. Added banana.gif to the project

  2. Added code to add banana attachment into NotificationService.m

    self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];

    // Add image attachment
    NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"banana" withExtension:@"gif"];
    NSError *error;
    UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"banana" URL:fileURL options:nil error:&error];
    self.bestAttemptContent.attachments = @[attachment];

What did I miss?

Additional info: The same thing works when I use local notifications instead of remote notifications.

gklka
  • 2,459
  • 1
  • 26
  • 53

1 Answers1

3

You're most of the way there. The way you're going to send the attachment is usually as a URL in your payload. However, if you wanted to hard-code the attachment, like your code does, I think it would work, but I think you missed one critical component. I think the service extension does not have access to the main bundle or its resources. If you added a resource to the service extension and tried to load that (using something like [NSBundle bundleForClass:[NotificationService class]]), I suspect it would work.

However, if you send the URL as part of the payload, then you're going to load the image from that URL and not the bundle anyway. In that case, I'm pretty sure you also have to use startAccessingSecurityScopedResource on NSURL (along with stopAccessingSecurityScopedResource).

Hope that helps!

Jerry
  • 4,382
  • 2
  • 35
  • 29
  • Good idea, I've tried it and have two questions: 1. why does the "[modified]" title modification thing not work then? 2. I've modified the project on the URL to support file downloading, and sending the following push: https://gist.github.com/gklka/9802bb56340c38a7a481cde2c4fcaa70 It does not seem to work either. – gklka Oct 18 '16 at 06:26
  • Is `serviceExtensionTimeWillExpire()` getting called? If you run the extension from Xcode (not the app), can you hit breakpoints in either method? – Jerry Oct 18 '16 at 13:54
  • Neither `NSLog`, nor putting breakpoints into `NotificationService.m` seems working. Maybe I missed something? Could you please check my project on GitHub? https://github.com/gklka/RichTest – gklka Oct 18 '16 at 18:29
  • Using your exact project, and the push script from this tutorial: https://www.raywenderlich.com/123862/push-notifications-tutorial modified with the answer from this question: http://stackoverflow.com/questions/28221224/push-notification-in-php-using-pem-file, I get the modified title. – Jerry Oct 19 '16 at 02:01
  • You'll still need to fix the code for the URL handling: 1. you're calling moveItemAtURL to move data from the web URL (from the original attachment) to a file URL (for the modified attachment). I suspect you meant for the first parameter to be `location` not `url`, but I don't know if you need to move it before creating the attachment. 2. You'll need to use the security scoped resource methods I mentioned in my original answer. – Jerry Oct 19 '16 at 02:04
  • Of course, make sure you're testing on a device and not the simulator. I'm sure you are, just double checking. – Jerry Oct 19 '16 at 02:05
  • Thank you very much, the problem was with Boodle, the app I use for sending test notifications. The PHP you linked works fine! Also thank you for pointing out the issue about moving file to temp location. – gklka Oct 19 '16 at 07:03