iOS-简单集成APNS推送

2,133 阅读3分钟

一.ANPS 原理

  • 1.App在代码中注册消息推送弹框 ;
  • 2.iOSANPS服务器获取Device Token,回传给APP;
  • 3.APPDevice Token 发送给自己公司服务器;
  • 4.APP 发消息到自己公司服务器后,自己公司服务器将要发送的消息,目的iPhone的标识打包发送给ANPS服务器;
  • 5.ANPS服务器在自身的已注册Push服务的设备列表中,查找有相应标识的设备,并把消息发送到设备的APP,并且按照设定弹出Push通知。

二.APNS原理图:

APNS原理图.png

三.项目集成APNS推送过程

  • 1.创建推送证书

    • 从钥匙串中创建CRS文件,具体操作步骤见下图:

    CSR文件第一步.png CSR文件第二步.png CSR文件第三步.png

  • 2.创建推送证书

    • 登录开发者网站->登录账号->创建push推送证书(Development+Distribute)->下载证书->从钥匙串中导出P12证书-发送给公司服务器

    创建证书第一步.png 创建证书第二步.png

    创建证书第三步.png

  • 3.创建代码

    • 注册APNS推送请求

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中添加如下代码:

//APNS推送
    if (kDeviceSystemVersion >= 10.0) {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        center.delegate = self;
        UNAuthorizationOptions type = UNAuthorizationOptionAlert|UNAuthorizationOptionBadge|UNAuthorizationOptionSound;
        [center requestAuthorizationWithOptions:type completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                NSLog(@"注册APNS成功");
                dispatch_async(dispatch_get_main_queue(), ^{
                    [[UIApplication sharedApplication] registerForRemoteNotifications];
                });
                
            } else {
                NSLog(@"注册APNS失败");
            }
        }];
        
    } else if(kDeviceSystemVersion >= 8.0){
        UIUserNotificationType type = UIUserNotificationTypeAlert|UIUserNotificationTypeSound|UIUserNotificationTypeBadge;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    } else {
        UIRemoteNotificationType type = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:type];
    }
  • 程序第一次安装的请求弹框如下图:

    注册push弹框.png

    • 点击允许后应用接收device token 注册device token成功,调用如下代码:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    //iOS13 后
    NSMutableString *tokenString = [NSMutableString string];
    const char *bytes = deviceToken.bytes;
    int iCount = deviceToken.length;
    for (int i = 0; i < iCount; i++) {
        [tokenString appendFormat:@"%02x", bytes[i]&0x000000FF];
    }
    
    NSLog(@"tokenString = %@", tokenString);
   
    [[NSUserDefaults standardUserDefaults] setObject:tokenString forKey:@"DeviceTokenString"];
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"autoRemotePush"];
    if (![[NSUserDefaults standardUserDefaults] boolForKey:@"pushToken"] && [[NSUserDefaults standardUserDefaults] objectForKey:@"DeviceTokenString"]) {
        [self pushToken:tokenString];
    }
    
}
  • 注册device token失败,调用如下代码
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}
  • 将devicetoken 推送给自己公司服务器,推送代码自行编写
  • 4.接收push消息
    • iOS10以上的通知用UNUserNotificationDelegate接收通知 程序退到后台接收push推送
//ios10之后 应用在后台接收推送消息
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler {
    NSLog(@"%s", __func__);

    NSDictionary * userInfo = response.notification.request.content.userInfo;
    NSDictionary *apsDic = [userInfo objectForKey:@"aps"];

    UIApplication *application = [UIApplication sharedApplication];

    if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [self receivedNotification:userInfo application:application];
    }
    else {
        // 判断为本地通知

    }

    // Warning: UNUserNotificationCenter delegate received call to
    completionHandler();  // 系统要求执行这个方法
}
  • iOS10应用在前台收到push 消息
//ios10 应用在前台是否接收推送消息
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler API_AVAILABLE(ios(10.0)){
    NSLog(@"%s", __func__);
    
    
    NSDictionary * userInfo = notification.request.content.userInfo;
    NSDictionary *apsDic = [userInfo objectForKey:@"aps"];
    
    UIApplication *application = [UIApplication sharedApplication];
    
    if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [self receivedNotification:userInfo application:application];
    }
    else {
        // 判断为本地通知
        
    }
 
    
}
  • iOS10 以下系统收到push 消息
//ios3-ios10 收到推送消息
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

    [self receivedNotification:userInfo application:application];
    
}

//ios7 点击推送消息进入
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    [self receivedNotification:userInfo application:application];
    completionHandler(UIBackgroundFetchResultNewData);
}
  • 5.程序被杀死,点击通知栏的push消息
if ([[launchOptions allKeys] containsObject:UIApplicationLaunchOptionsRemoteNotificationKey]) {//用户是点击通知栏推送启动的
        
        NSDictionary *remoteNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
        //        NSDictionary *apsDic = [remoteNotification objectForKey:@"aps"];
        
        //        NSString *message = [apsDic objectForKey:@"alert"];
        //        NSString *badge = [apsDic objectForKey:@"badge"];//红点数量
        //        NSString *sound = [apsDic objectForKey:@"sound"];//声音
        [self receivedNotification:remoteNotification application:application];
        
        NSUserDefaults *notificationDic = [NSUserDefaults standardUserDefaults];
        [notificationDic setObject:remoteNotification forKey:@"notification"];
        
    }else{
        NSLog(@"用户是正常启动的程序");
    }
  • 6.处理推送消息,代码自行编写

四.注意说明

  • 应用图标的applicationIconBadgeNumber变化由 推送消息中的badge决定,接收消息的声音由 推送消息的sound 决定

记录这些吧 ,感谢阅读,如有错误,不吝赐教!