tencent cloud

Feedback

Offline Push (iOS)

Last updated: 2022-05-24 10:23:47

    Overview

    IM terminal users need to obtain the latest messages at any time. However, due to the limited performance and battery power of mobile devices, when the app is running in the background, IM recommends that you use the system-grade push channels (APNs) provided by Apple for message notifications to avoid excessive resource consumption caused by maintaining a persistent connection. Compared with third-party push, APNs provides more stable system-grade persistent connections, enabling users to receive push messages at any time and greatly reducing resource consumption.

    Note
    • If you want to continue to receive IM message notifications if, without proactive logout, the app switches to the background, the mobile phone screen is locked, or the app process is killed by a user, you can enable IM offline push.
    • If the app proactively calls the logout API to log out or is forced to log out due to multi-device login, you cannot receive offline push messages even if IM offline push is enabled.

    [](id:Configuring Offline Push)

    Configuring Offline Push

    If you want to receive APNs offline message notifications, follow these steps:

    1. Apply for APNs certificates.
    2. Upload the certificates to the IM console.
    3. The app requests deviceToken from Apple every time it logs in.
    4. Call setAPNS to report the token to the IM backend.

    Step 1: Apply for APNs certificates

    Activate the remote push service for your app

    1. Log in to the Apple Developer website and click Certificates, Identifiers & Profiles in the right pane or Certificates, IDs & Profiles in the left sidebar to enter the Certificates, IDs & Profiles page.

    2. Click + on the right of Identifiers.

    3. You can register an AppID by following the steps below or add the Push Notification service to your existing AppID.

      Note:

      Your Bundle ID cannot contain the wildcard *. Otherwise, you will be unable to use the remote push service.

    4. Select App IDs and click Continue.

    5. Select App and click Continue.

    6. Configure Bundle ID and other information. Click Continue.

    7. Check Push Notifications to activate the remote push service.

    Generating certificates

    1. Select your AppID and click Configure.

    2. In the Apple Push Notification service SSL Certificates window, you can see two SSL certificates: Development SSL Certificate and Production SSL Certificate.

    3. Click Create Certificate under Development SSL Certificate to create a certificate. You will be prompted that a Certificate Signing Request (CSR) is required.

    4. Open Keychain Access on Mac. Choose Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority.

    5. Fill in your email for User Email Address and your name or company name for Common Name. Select Saved to disk and click Continue. Then the system will generate a *.certSigningRequest file.

    6. Go back to the Apple Developer page shown in step 3 and click Choose File to upload the *.certSigningRequest file.

    7. Click Continue to generate the push certificate.

    8. Click Download to save the development SSL certificate locally.

    9. Repeat steps 1-8 to generate and download the production SSL certificate locally.

      Note:

      The production SSL certificate is in fact a Sandbox+Production certificate that can apply to both the development and production environments.

    10. Double-click and open the downloaded development SSL certificate and production SSL certificate to import them to Keychain Access.

    11. Open Keychain Access, choose Login > My Certificates, and right-click to export the P12 files generated for the development environment (Apple Development IOS Push Service) and production environment (Apple Push Services).

      Note:

      Remember to set the password when saving the P12 files.

    Step 2: Upload the certificates to the console

    1. Log in to the IM console.
    2. Click the target app card to go to its basic configuration page.
    3. Click Add Certificate on the right of iOS Native Offline Push.
    4. Choose the certificate type, upload an iOS certificate (.p12), set the certificate password, and click OK.
    Note:

    • We recommend that the names of the uploaded certificates be in English (special characters such as brackets are not allowed).
    • You need to set passwords for the uploaded certificates. Without a password, push messages cannot be received.
    • The environments of the certificates published on App Store must be the production environment. Otherwise, push messages cannot be received.
    • The uploaded P12 certificates must be authentic valid certificates applied for by yourself.

    1. After the push certificate information is generated, record the certificate IDs.

    Step 3: The app requests deviceToken from the Apple backend

    To request deviceToken from Apple's backend server, add the following code to your app.

    Note:

    For compliance considerations, we recommend that you request deviceToken from the Apple backend after the user agrees to the Privacy Policy.

    // Request deviceToken from the Apple backend
    - (void)registNotification
    {
      if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
      {
          [[UIApplication sharedApplication] registerUserNotificationSettings:
                  [UIUserNotificationSettings settingsForTypes:
                  (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)
                  categories:nil]];
          [[UIApplication sharedApplication] registerForRemoteNotifications];
      }
      else
      {
          [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
                  (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
      }
    }
    // The callback of AppDelegate returns deviceToken, which needs to be reported to the Tencent Cloud backend after login.
    -(void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
      // Note the deviceToken returned by Apple.
      _deviceToken = deviceToken;
    }
    

    Step 4: Log in to IM SDK and upload deviceToken to Tencent Cloud

    After logging in to the IM SDK, call the setAPNS API to upload the deviceToken obtained in step 3 to the Tencent Cloud backend. The following is the sample code. For more information, see TUIKitDemo.

    - (void)push_registerIfLogined:(NSString *)userID
    {
      NSLog(@"[PUSH] %s, %@", __func__, userID);
      BOOL supportTPNS = NO;
      if ([self respondsToSelector:@selector(supportTPNS:)]) {
          supportTPNS = [self supportTPNS:userID];
      }
      
      if (self.deviceToken) {
          V2TIMAPNSConfig *confg = [[V2TIMAPNSConfig alloc] init];
          /* Users need to register a developer certificate with Apple, download and generate the certificate (P12 file) in their developer accounts, and upload the generated P12 file to the Tencent certificate console. The console will automatically generate a certificate ID and pass it to the `businessID` parameter.*/
          // Push certificate ID
          confg.businessID = sdkBusiId;
          confg.token = self.deviceToken;
          [[V2TIMManager sharedInstance] setAPNS:confg succ:^{
               NSLog(@"%s, succ, %@", __func__, supportTPNS ? @"TPNS": @"APNS");
          } fail:^(int code, NSString *msg) {
               NSLog(@"%s, fail, %d, %@", __func__, code, msg);
          }];
      }
      // ...
    }
    
    Note:

    businessID must be consistent with the certificate ID assigned by the console.

    Push Format

    General push rules

    For one-to-one messages, the APNs push format is as follows. Nickname indicates the sender's nickname. If no nickname is specified, only content is displayed.

    Nickname: Content
    

    For group messages, the APNs push format is as follows. The display priority for Name is: sender's Group name card > Group nickname. If neither is available, no name is displayed.

    Name (group name): Content
    

    Push rules for different types of messages

    The APNs push content consists of the content of each Elem in the message body. The display of different Elem in offline messages is shown in the following table.

    Parameter Description
    Text Elem Directly display the content
    Audio Elem Display [audio]
    File Elem Display [file]
    Image Elem Display [image]
    Custom Elem Display the desc field set when message is sent. If desc is not set, it will not be pushed.
    Note:

    If the default push rules do not meet your requirements, you can customize your own push rule. For more information, see Setting Custom Display for Offline Push.

    Communication among multiple apps

    If you want multiple apps to receive push message from each other, you can set SDKAppID to the same value for the apps.

    Note:

    Different apps need to use different push certificates, and you need to apply for APNs certificates for each app and [configure offline push](#Configuring Offline Push).

    Customizing the Badge Number

    • By default, when an app goes to the background, the IM SDK sets the current total unread message count of IM as the badge number.
    • If you want to customize the badge number, follow the steps below:
    1. Use the app to call the - (void)setAPNSListener:(id)apnsListener API to configure listening.
    2. Use the app to implement the - (uint32_t)onSetAPPUnreadCount API and return the badge number to be customized internally.
    • If offline push is enabled in the app, and a new offline push message is received, the badge number of the app will be increased by one based on the benchmark badge number (which is the total unread message count of IM by default and is the custom badge number if there is any).
      // 1. Configure listening
    • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      // Listen for push messages
      [V2TIMManager.sharedInstance setAPNSListener:self];
      // Listen for the unread message counts of conversations
      [[V2TIMManager sharedInstance] setConversationListener:self];
      return YES;
      }
      // 2. When the unread message count changes, save the new unread message count
    • (void)onTotalUnreadMessageCountChanged:(UInt64)totalUnreadCount {
      self.unreadNumber = totalUnreadCount;
      }

    // 3. The app goes to the background and reports the custom unread message count
    /** After the app goes to the background, customize the unread message count of the app. If you do not customize the unread message count, the sum of the unread message counts of all conversations is used as the unread message count of the app.

    • <pre>
      • (uint32_t)onSetAPPUnreadCount {
    •   return 100;  // Custom unread message count
      
    • }
    • </pre>
    • /
    • (uint32_t)onSetAPPUnreadCount {
      // 1. Get the custom badge number
      uint32_t customBadgeNumber = ... // 2. Add the unread message count of IM
      customBadgeNumber += self.unreadNumber; // 3. Use the IM SDK to report to the IM server
      return customBadgeNumber;
      }

    Customizing Push Alert Sounds

    iOS push alert sound

    When calling sendMessage to send messages, set the iOSSound field in offlinePushInfo to the name of the audio file.

    Note:

    • Offline push sound setting is valid only for iOS. When iOSSound is kIOSOfflinePushNoSound, no sound is played when a push message is received.
    • When iOSSound is kIOSOfflinePushDefaultSound, the system alert sound is played when a push message is received.
    • To customize iOSSound, link the audio file to the Xcode project and set iOSSound to the audio filename (with the extension name).
    V2TIMOfflinePushInfo *pushInfo = [[V2TIMOfflinePushInfo alloc] init];
    pushInfo.title = @"push title";
    pushInfo.iOSSound = @"phone_ringing.mp3"; // Name of your audio file
    [[V2TIMManager sharedInstance] sendMessage:msg receiver:receiver groupID:groupID priority:V2TIM_PRIORITY_DEFAULT onlineUserOnly:NO offlinePushInfo:pushInfo progress:nil succ:^{
    } fail:^(int code, NSString *msg) {
    }];
    

    Android push alert sound

    When calling sendMessage to send messages, set the AndroidSound field in offlinePushInfo to the name of the audio file.

    Note:

    • For offline push sound setting (valid only for Android and supported by IM SDK 6.1 or later), only Huawei and Google mobile phones support ringtone setting.
    • For Mi ringtone setting, see https://dev.mi.com/console/doc/detail?pId=1278%23_3_0.
    • To customize AndroidSound, you need to place the audio file to the raw directory of the Android project and set the audio file name (without the file extension) as the value of AndroidSound.
    V2TIMOfflinePushInfo *pushInfo = [[V2TIMOfflinePushInfo alloc] init];
    pushInfo.title = @"push title";
    pushInfo.AndroidSound = @"phone_ringing"; // your voice file's name
    [[V2TIMManager sharedInstance] sendMessage:msg receiver:receiver groupID:groupID priority:V2TIM_PRIORITY_DEFAULT onlineUserOnly:NO offlinePushInfo:pushInfo progress:nil succ:^{
    } fail:^(int code, NSString *msg) {
    }];
    

    Customizing the Display for Offline Push

    When calling sendMessage to send messages, set the title and desc fields in offlinePushInfo. Once set, the title content will be added to the default push content and desc will be displayed as the push content.

    V2TIMOfflinePushInfo *info = [[V2TIMOfflinePushInfo alloc] init];
    info.title = @"Harvy";                        // Offline push display title
    info.desc = @"You have a call invitation.";   // Offline push display content
    // `receiver` and `groupID` cannot be empty at the same time, and only one of them can be set.
    [[V2TIMManager sharedInstance] sendMessage:msg receiver:receiver groupID:groupID priority:V2TIM_PRIORITY_DEFAULT onlineUserOnly:NO offlinePushInfo:pushInfo progress:nil succ:^{
    } fail:^(int code, NSString *msg) {
    }];
    

    Note:

    You can also use the multable-content field of APNs and NSNotification Service Extension to customize the display content. If you have any questions or feedback, feel free to contact us.

    Customizing Click-to-Redirect Logic

    When calling sendMessage to send messages, set the ext field in offlinePushInfo. When the user receives an offline push message and starts the app, the ext field can be obtained from the AppDelegate -> didReceiveRemoteNotification system callback, and the user is redirected to the UI as specified by ext. For more information, see TUIKitDemo.

    The following example assumes that Denny sends a message to Vinson.

    • Sender: Denny needs to set ext before sending a message.

      // Denny sets `offlinePushInfo` and specifies `ext` before sending a message
      V2TIMMessage *msg = [[V2TIMManager sharedInstance] createTextMessage:@"Text message"];
      V2TIMOfflinePushInfo *info = [[V2TIMOfflinePushInfo alloc] init];
      info.ext = @"jump to denny";
      [[V2TIMManager sharedInstance] sendMessage:msg receiver:@"vinson" groupID:nil priority:V2TIM_PRIORITY_DEFAULT
      onlineUserOnly:NO offlinePushInfo:info progress:^(uint32_t progress) {
      } succ:^{
      } fail:^(int code, NSString *msg) {
      }];
      
    • Recipient: Although Vinson's app is not online, it can still receive an APNs offline message notification. When Vinson clicks this notification, the app is started.

      // Vinson receives the following callback when the app is started.
      - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 
      fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
       // Resolve the extension field `desc`.
       if ([userInfo[@"ext"] isEqualToString:@"jump to denny"]) {
           // Go to the chat window with Denny.
       }
      }
      

    FAQs

    Why doesn't offline push work for common messages?

    First, verify that the app runtime environment is the same as the certificate environment. Otherwise, offline push messages will not be received.
    Then, verify that the app and the certificate run in the development environment. If that is the case, requesting deviceToken from Apple might fail. Please switch to the production environment to solve the problem.

    Why doesn't offline push work for custom messages?

    The offline push for custom messages is different from that for common messages. Since we are not able to resolve the content of custom messages and determine what to push, we simply do not push custom messages by default. If you want to enable offline push for custom messages, set the desc field in offlinePushInfo when calling sendMessage. Then, the content of desc will be displayed by default for offline push.

    How do I disable the receiving of offline push messages?

    To disable the receiving of offline push messages, set the config parameter of the setAPNS API to nil. This feature is supported from v5.6.1200.

    What should I do if push messages cannot be received and the backend reports the "bad devicetoken" error?

    For Apple devices, deviceToken is related to the current compilation environment. If the certificate ID used to upload deviceToken to Tencent Cloud after logging in to IM SDK is inconsistent with the environment token, the error will be reported.

    • If the compilation environment is Release, - application:didRegisterForRemoteNotificationsWithDeviceToken: calls back the release environment token, businessID must be set to the certificate ID of the production environment.
    • If the compilation environment is Debug, - application:didRegisterForRemoteNotificationsWithDeviceToken: calls back the development environment token, businessID must be set to the certificate ID of the development environment.
    V2TIMAPNSConfig *confg = [[V2TIMAPNSConfig alloc] init];
    /* Users need to register a developer certificate with Apple, download and generate the certificate (P12 file) in their developer accounts, and upload the generated P12 file to the Tencent certificate console. The console will automatically generate a certificate ID and pass it to the `businessID` parameter.*/
    // Push certificate ID
    confg.businessID = sdkBusiId;
    confg.token = self.deviceToken;
    [[V2TIMManager sharedInstance] setAPNS:confg succ:^{
       NSLog(@"%s, succ, %@", __func__, supportTPNS ? @"TPNS": @"APNS");
    } fail:^(int code, NSString *msg) {
       NSLog(@"%s, fail, %d, %@", __func__, code, msg);
    }];
    

    What should I do if deviceToken is not returned for registration occasionally or APNs' request for token fails in the iOS development environment?

    This problem is caused by instability of APNs. You can fix it in the following ways:

    1. Insert a SIM card into the phone and use the 4G network.
    2. Uninstall and reinstall the application, restart the application, or shut down and restart the phone.
    3. Use a package for the production environment.
    4. Use another iPhone.
    Contact Us

    Contact our sales team or business advisors to help your business.

    Technical Support

    Open a ticket if you're looking for further assistance. Our Ticket is 7x24 avaliable.

    7x24 Phone Support