logoDocument
Search
Login

Push Icon Configuration Guide

This document aims to guide users on how to set notification bar small icons, right-side icons, and large images. alt text

📱 iOS Icon Setup Methods

Small Icon Setup

Go to Images.xcassets-AppIcon and set the iPhone Notification icon with the following dimensions:

  • 40 x 40px
  • 60 x 60px

alt text

Right-side Icon / Large Image Setup

✅ Supported Versions

  • Supported on iOS 10 and above starting from EngageLab iOS SDK v3.0.0.

🧑‍💻 Client Setup

  1. Create a Service Extension service.

  2. Add the mtpush-extension-ios-xxx.xcframework file to your Service Extension project.

  3. Add the following two frameworks:

    • libz.tbd
    • libresolv.tbd
  4. Call the [mtpushSetAppkey:] method to set the AppKey (ensure it matches the AppKey used when creating the AppPush application).

  5. In the [didReceiveNotificationRequest:] callback, retrieve the image link. Example code is as follows:

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { self.contentHandler = contentHandler; self.bestAttemptContent = [request.content mutableCopy]; self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [NotificationService]", self.bestAttemptContent.title]; NSString * attachmentPath = self.bestAttemptContent.userInfo[@"my-attachment"]; //if exist if (attachmentPath) { //download NSURL *fileURL = [NSURL URLWithString:attachmentPath]; [self downloadAndSave:fileURL handler:^(NSString *localPath) { if (localPath) {UNNotificationAttachment * attachment = [UNNotificationAttachment attachmentWithIdentifier:@"myAttachment" URL:[NSURL fileURLWithPath:localPath] options:nil error:nil]; self.bestAttemptContent.attachments = @[attachment]; } [self apnsDeliverWith:request]; }]; }else{[self apnsDeliverWith:request]; } } - (void)downloadAndSave:(NSURL *)fileURL handler:(void (^)(NSString *))handler { NSURLSession * session = [NSURLSession sharedSession]; NSURLSessionDownloadTask *task = [session downloadTaskWithURL:fileURL completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSString *localPath = nil; if (!error) {NSString * localURL = [NSString stringWithFormat:@"%@/%@", NSTemporaryDirectory(),fileURL.lastPathComponent]; if ([[NSFileManager defaultManager] moveItemAtPath:location.path toPath:localURL error:nil]) {localPath = localURL;} } handler(localPath); }]; [task resume]; }
              
              - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
  self.contentHandler = contentHandler;
  self.bestAttemptContent = [request.content mutableCopy];
  self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [NotificationService]", self.bestAttemptContent.title];
  
  NSString * attachmentPath = self.bestAttemptContent.userInfo[@"my-attachment"];
  //if exist
  if (attachmentPath) {
    //download
    NSURL *fileURL = [NSURL URLWithString:attachmentPath];
    [self downloadAndSave:fileURL handler:^(NSString *localPath) {
      if (localPath) {UNNotificationAttachment * attachment = [UNNotificationAttachment attachmentWithIdentifier:@"myAttachment" URL:[NSURL fileURLWithPath:localPath] options:nil error:nil];
        self.bestAttemptContent.attachments = @[attachment];
      }
      [self apnsDeliverWith:request];
    }];
  }else{[self apnsDeliverWith:request];
  }
}

- (void)downloadAndSave:(NSURL *)fileURL handler:(void (^)(NSString *))handler {
  NSURLSession * session = [NSURLSession sharedSession];
  NSURLSessionDownloadTask *task = [session downloadTaskWithURL:fileURL completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    NSString *localPath = nil;
    if (!error) {NSString * localURL = [NSString stringWithFormat:@"%@/%@", NSTemporaryDirectory(),fileURL.lastPathComponent];
      if ([[NSFileManager defaultManager] moveItemAtPath:location.path toPath:localURL error:nil]) {localPath = localURL;}
    }
    handler(localPath);
  }];
  [task resume];
}

            
This code block in the floating window

🌐 Server-side Setup

Configure the mutable-content and extras fields under ios:

Field Name Type Required Parent Field Description
mutable-content boolean Optional notification.ios Enable notification extension. Set to true to support iOS 10's UNNotificationServiceExtension.
extras JSON Object Optional notification.ios Additional fields. The key (e.g., my-attachment) must match the client code.

Example JSON:

"notification": { "ios": { "alert": { "title": "title", "subtitle": "subtitle" }, "mutable-content": true, "extras": { "my-attachment": "https://raw.githubusercontent.com/Tikon/imgRepo/master/ic_launcher.png" } } }
              
              "notification": {
  "ios": {
    "alert": {
      "title": "title",
      "subtitle": "subtitle"
    },
    "mutable-content": true,
    "extras": {
      "my-attachment": "https://raw.githubusercontent.com/Tikon/imgRepo/master/ic_launcher.png"
    }
  }
}

            
This code block in the floating window

🤖 Android Icon Setup Methods

✅ Supported Versions

Supported starting from EngageLab Android SDK v4.4.0.

📡 Channel Support

Channel Dynamic Small Icon Right-side Icon Large Image
EngageLab ✅ (System Supported) ✅ (Except Meizu) ✅ (System Supported)
Xiaomi
Huawei ✅ (Service/Info)
Honor ✅ (Not Supported for Marketing)
OPPO
FCM
Meizu
vivo

📝 Notes:

  • OPPO: When the push target exceeds 20 and ColorOS version > 5.0, the first notification displays a large image under WiFi.
  • Xiaomi: As of August 2023, dynamic icon and large image settings are no longer supported during push.

🎨 Small Icon Setup

🧑‍💻 Client Setup

  • If the project contains the res/drawable/mtpush_notification_icon resource, it will be used as the default icon.
  • If this resource is absent, the application icon will be used by default.

FCM Channel Configuration Example:

<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/mtpush_notification_icon" /> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/colorAccent" />
              
              <meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/mtpush_notification_icon" />
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />

            
This code block in the floating window

🌐 Server-side Setup

Field Name Type Required Parent Field Description
small_icon string Optional notification.android Network icon link or image resource path, size must not exceed 300k
small_icon_uri string Optional options.third_party_channel.vendor Vendor channel icon style, currently only supported by Huawei

Example JSON:

"notification": { "android": { "alert": "Hi, Push!", "title": "Send to Android", "small_icon": "logo" } }, "options": { "time_to_live": 60, "third_party_channel": { "huawei": { "distribution_new": "pns_mtpush", "small_icon_uri": "https://res.engagelab.net/oversea/e/website/2025/_nuxt/app-push.II1rRaB5.webp" } } }
              
              "notification": {
  "android": {
    "alert": "Hi, Push!",
    "title": "Send to Android",
    "small_icon": "logo"
  }
},
"options": {
  "time_to_live": 60,
  "third_party_channel": {
    "huawei": {
      "distribution_new": "pns_mtpush",
      "small_icon_uri": "https://res.engagelab.net/oversea/e/website/2025/_nuxt/app-push.II1rRaB5.webp"
    }
  }
}

            
This code block in the floating window

🖼️ Right-side Icon / Large Image Setup

🌐 Server-side Field Description

Field Name Type Required Parent Field Description
style int Optional notification.android Notification bar style type: Default 0, 1=bigText, 2=Inbox, 3=bigPicture
big_pic_path string Optional notification.android Effective when style=3. Can set URL or local path
large_icon string Optional notification.android Right-side icon, network image or drawable resource path, size must not exceed 300k

Example JSON:

{ "notification": { "android": { "alert": "Hi, Push!", "title": "Send to Android", "large_icon": "logo", "big_pic_path": "https://scpic.chinaz.net/files/pic/pic9/201311/apic2098.jpg", "style": 3 } }, "options": { "third_party_channel": { "huawei": { "distribution_new": "pns_mtpush", "large_icon": "https://scpic.chinaz.net/files/pic/pic9/201311/apic2098.jpg" } } } }
              
              {
  "notification": {
    "android": {
      "alert": "Hi, Push!",
      "title": "Send to Android",
      "large_icon": "logo",
      "big_pic_path": "https://scpic.chinaz.net/files/pic/pic9/201311/apic2098.jpg",
      "style": 3
    }
  },
  "options": {
    "third_party_channel": {
      "huawei": {
        "distribution_new": "pns_mtpush",
        "large_icon": "https://scpic.chinaz.net/files/pic/pic9/201311/apic2098.jpg"
      }
    }
  }
}

            
This code block in the floating window

❓ FAQ

1. Displayed as gray?

  • On native Android 5.0 and above, if the app's targetSdkVersion ≥ 21, the system will forcefully apply a mask color to notification small icons, causing them to appear gray. To ensure good contour and recognizability, it is recommended to use hollow icons without shadows, gradients, or backgrounds, and name them as mtpush_notification_icon, replacing the same-named file in the res/drawable directory of the project. Additionally, ensure that all icon files related to notification icons (e.g., drawable-xxhdpi for different densities) in the res directory are uniformly replaced with new icon resources. After proper setup, the system will display a compliant gray contour icon, avoiding abnormal or unclear icon issues.
  • Due to restrictions on some systems (e.g., OnePlus phones, Google phones with Android 10), this cannot be resolved.
  • Xiaomi phone launchers may cache icons. After configuring as required above, restart the phone and test again.
  • For Xiaomi phones, whether using the EngageLab channel or Xiaomi channel, switching to the native style is required for it to take effect. The switching method is as follows: alt text

2. Icon change ineffective?

  • The system or vendor service may cache icons (this may occur on Xiaomi and Meizu phones).
  • It is recommended to uninstall the app, restart the phone, and then reinstall the new version.

Icon/Image not displaying?

  1. EngageLab Channel: Check if the default notification bar style builder interface has been called. If so, remove the interface, uninstall the app, and try again.
  2. APNs (iOS): The right-side icon and large image are the same image. In the foreground, the notification dropdown displays the large image, while in other cases, only the right-side icon is displayed.
  3. FCM (Android): Before expansion, the right-side icon is displayed; after expansion, the large image is displayed. alt text
icon
Contact Sales