iOS集成指南

准备工作

生成APNS证书

1. 在iOS开发者中心: iOS Provisioning Portal创建一个AppID,如图:

image

image

2. 生成iOS Push Service证书,如图:

image

image

image

image

image

image

image

回到iOS Provisioning Portal:

image

image

image

image

点击“Download”下载iOS Push Service证书文件,如图:

image

3. 导入证书文件到keychain:双击即可

image

4. 生成cert.p12

image

image

5. 生成并安装Profile文件:

image

image

image

image

image

image

image

6. 在配置Service的地方上传cert.p12到推送宝

下载SDK

通过下载SDK页面下载 iOS SDK 并解压。

导入SDK

  • 通过 Xcode 打开您的 App 工程
  • 选择 File -> Add Files to 'Your project name'...,将下图中指示的文件从下载的 SDK 中导入:

image

配置详解

调用初始化方法

应用程序启动时,需要调用推送宝的初始化方法,完成对推送宝环境的初始化。

  • AppDelegate.h

      #import "PushManager.h"
    
      @interface AppDelegate : UIResponder <UIApplicationDelegate, PushManagerDelegate, PushLocationManagerDelegate>
    
  • AppDelegate.m

    
      #define IS_IOS8 [[[UIDevice currentDevice] systemVersion] integerValue] >= 8
    
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
          ....
    
          [[PushManager sharedInstance] initPushManagerWithAppID:@"appId"
                                                       apiScrect:@"apiScrect"
                                                      enviroment:PushEnviromentTypeDevelop
                                                        delegate:self];
          [[PushManager sharedInstance] didFinishLaunchingWithOptions:launchOptions];
    
          if (IS_IOS8) {
              [[UIApplication sharedApplication] registerForRemoteNotifications];
              [[UIApplication sharedApplication]
                  registerUserNotificationSettings:
                      [UIUserNotificationSettings
                          settingsForTypes:(UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge |
                                            UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeNone)
                                categories:nil]];
          } else {
              [[UIApplication sharedApplication]
                  registerForRemoteNotificationTypes:UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge |
                                                     UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeNone];
          }
    
          return YES;
      }
    
集成推送宝时需要配置当前使用的 APNs 环境 PushEnviromentType, PushEnviromentTypeDevelop 为 APNs 的测试环境,为开发测试时使用;PushEnviromentTypeProduction 为 APNs 的生产环境,在 App Store 发布时使用。

设备注册

修改应用的 delegate,加入如下代码:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    // Required
    [[PushManager sharedInstance] didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    // Required
    [[PushManager sharedInstance] didFailToRegisterForRemoteNotificationsWithError:error];
}

接收消息

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    // Required
    [[PushManager sharedInstance] didReceiveRemoteNotification:userInfo];

    ...
}

其它API

[[PushManager sharedInstance] registerWithTag:@"MyTag"];
[[PushManager sharedInstance] registerWithTags:@[@"MyTag1", @"MyTag2", ...]];  // 支持同时注册多个Tag

API说明

推送消息时,可以将特定的消息推送给特定的用户。为了对他们进行标识,可以给他们制定不同的标签。请尽量使用英文字母,数字,下划线, 中文等常用字符,以免因为字符格式导致注册标签失败。

[[PushManager sharedInstance] unregisterWithTag:@"MyTag"];
[[PushManager sharedInstance] unregisterWithTags:@[@"MyTag1", @"MyTag2", ...]];  // 支持同时取消多个Tag

API说明

解除指定的标签。该用户将不再收到发送给该标签的消息。

[[PushManager sharedInstance] registerWithUserVars:@{@"registedKey" : @"value"}];

API说明

注册用户变量。使得同一个消息发给不同的设备可以产生不同的消息内容。

[[PushManager sharedInstance] getGeoFencesFromWebSite];

API说明

同步地理围栏。调用该方法会同步服务端的 GeoFences,并且自动添加到地理围栏的监控中。注:此功能依赖于用户对地理位置服务的授权

[[PushManager sharedInstance] setAlias:@"MyAlias"]; // v2.1.6 新增

API说明

给设备设置别名。同一个设备只能绑定一个别名,新的别名会覆盖旧的。

[[PushManager sharedInstance] setBadge:10];

API说明

设置设备当前的 badge 值,推送宝会在服务端统一管理,推送时可便捷的对该值进行增减,开发者无需自己维护每个设备的 badge 值。详情参见Open API

回调函数

@interface AppDelegate : UIResponder <UIApplicationDelegate, PushManagerDelegate>

#pragma mark Push IO

- (void)readyForRegistration {
    NSLog(@"Getting token from APNs successfully");
}

集成 Geo Fence 消息推送

权限配置

  1. 必须 启用 后台应用程序刷新

    However, when a user disables the Background App Refresh setting either globally or specifically for your app, the system doesn’t relaunch your app for any location events, including significant-change or region monitoring events. Further, while Background App Refresh is off your app won’t receive significant-change or region monitoring events even when it’s in the foreground. When a user reenables Background App Refresh for your app, Core Location restores all background services, including any previously registered regions.

    因此,需要在 plist 文件中设置 Background Modes,可以启用 Background fetch。此外,对于 iOS 8+ 的设备,仅用 Location updates 不能令应用使用 后台应用程序刷新 的功能。

  2. plist 文件中设置 NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription 的描述:

    • NSLocationWhenInUseUsageDescription

      describes the reason why the app accesses the user’s location normally while running in the foreground.

    • NSLocationAlwaysUsageDescription

      describes the reason why the app accesses the user’s location information. Include this key when your app uses location services in a potentially nonobvious way while running in the foreground or the background.

      请根据您的需求选取相应的设置,这将会影响到 是否有权限获取系统发送的位置更新。建议使用 NSLocationAlwaysUsageDescription,以获得更精准的 Geo Fence 服务。

启用 Location Service

application:didFinishLaunchingWithOptions: 方法中调用如下代码:

[[PushManager sharedInstance] startLocationSevice:YES];

注意事项

  1. 回调中执行代码的方式

    In iOS, regions associated with your app are tracked at all times, including when the app isn’t running. If a region boundary is crossed while an app isn’t running, that app is relaunched into the background to handle the event. Similarly, if the app is suspended when the event occurs, it’s woken up and given a short amount of time (around 10 seconds) to handle the event. When necessary, an app can request more background execution time using the beginBackgroundTaskWithExpirationHandler: method of the UIApplication class.

    SDK 也是在系统的回调中调用 PushLocationManagerDelegate 中实现的回调方法,因此,开发者应注意回调方法执行的时间。

  2. 因为根据手机信号塔定位的精度约为 500 米 ~ 10 千米,因此,Geo fence 的半径应大于 250 米。了解更多

参考资料

常见问题

丢消息

  • APNs 对 Offline 消息的规则保留最新的一条

    If APNs attempts to deliver a notification but the device is offline, the notification is stored for a limited period of time, and delivered to the device when it becomes available.

    Only one recent notification for a particular app is stored. If multiple notifications are sent while the device is offline, each new notification causes the prior notification to be discarded. This behavior of keeping only the newest notification is referred to as coalescing notifications.

    If the device remains offline for a long time, any notifications that were being stored for it are discarded.

    因此,如果网络不好,而此时又陆续发了 多条消息 给同一个设备,当设备的网络恢复时,只能收到最新的一条。

  • 对于 iOS 9+ 的设备,卸载应用后再重装会导致 token 的改变,自动更新时 token 不改变。由于开发过程中会遇到卸载再安装应用的情况,因此必须确保每次都有 打开应用 以获取最新的 token, 从而更新服务器的数据。因为用老的 token 发消息,设备是收不到的,同时 APNs 也 不会报错;用最新的 token 发消息相应设备才能收到。

  • 只是通过查看 Notification Center 里的消息来判断是否丢消息是不准确的。当未读消息过多时,消息有时会无端消失,目前来看是 iOS 的 bug

Geo Fence 没有触发或者触发不及时

检查是否符合触发的条件:

  1. Location Service 必须开启,并且允许您的应用使用。
  2. 设置 -> 通用 -> 后台应用程序刷新 的列表中应包含您的应用。
  3. 手机信号正常。
  4. 手机电量充足。当手机电量过低时,iOS 系统会为了续航而停止 Location Service。

如果因为 1 和 2 的条件不满足,重新开启相关权限,Core Location 会恢复所有已经注册过的 Geo Fence 并开始进行监控。

此外,Geo Fence 监控的准确性高度依赖于 手机信号塔Wi-Fi 路由器密度,因此如果手机网络信号不好或者在郊外,Geo Fence 的准确率会大大降低。了解更多

如果还不能确定原因,可以尝试记录日志的方式排查问题。在 TuisongbaoHost.plist 文件中添加键值 TSBAllowRecordLogInFile,设置其为 YES,SDK 会记录下相关信息。获取日志的步骤如下:

  1. 通过 USB 连接手机到 Xcode
  2. 进入 Window -> Devices,选择相应的设备,并选中应用
  3. 在应用列表的下方有一个齿轮图标的按钮,点击并选择 Download Container
  4. 将获取到的 xcappdata 文件发给推送宝
该方法并不全面,而且只能在测试期间有效。目前先用这个方式获取日志,以后会改进。

升级步骤

如无特殊说明,直接替换 SDK 即可。

v2.1.3 至 v2.1.4

  • 增加Location服务对于info-plist文件的配置。
  • 修改了初始化PushManager的方法,详见:PushManagerInit

v2.1.0 至 v2.1.1

  • 修改了初始化PushManager的方法,详见:PushManagerInit的描述。

v2.0.0 至 v2.1.0

  • 将framework替换为静态a文件。删除原PushYun.Framework,将2.0.0的文件添加到工程中,修改pushManager的引入方式。详见:PushManagerImport的描述。
  • 修改了PushManager和地理位置服务的初始化方法,详见:PushManagerInit的描述。
  Back To Top