美文网首页
远程推送(US)

远程推送(US)

作者: Harely | 来源:发表于2019-10-06 20:18 被阅读0次
远程通知原理示意图

第6阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone;
iPhone把发来的消息传递给相应的应用程序, 并且按照设定弹出Push通知。


远程通知中AppDelegate.m代理方法回调

// iOS<10时,且app被完全杀死
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

// 注:iOS10以上,如果不使用UNUserNotificationCenter,将走此回调方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo;

// iOS7及以上系统
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;

//  iOS>=10: App在前台获取到通知
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler;

//  iOS>=10: 点击通知进入App时触发(杀死/切到后台唤起)
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler;



不同版本远程注册通知处理

#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif

@interface AppDelegate () <UNUserNotificationCenterDelegate>

@end


//注册APNs消息
+ (void) registerRemoteNotification {
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 //Xcode8 编译会调用
        if (@available(iOS 10.0, *)) {
            UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
            center.delegate = self;
            [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError * _Nullable error) {
                if (!error) {
                    NSLog(@"request notification authorization succeeded!");
                }
            }];
        }
        [[UIApplication sharedApplication] registerForRemoteNotifications];
#else   //Xcode7 编译会调用
        UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge);
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes: types categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings: settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
#endif
    } else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
        UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge);
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes: types categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings: settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }else {
        UIRemoteNotificationType apn_type = (UIRemoteNotificationType)(UIRemoteNotificationTypeAlert |
                                                                       UIRemoteNotificationTypeSound |
                                                                       UIRemoteNotificationTypeBadge);
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:apn_type];
    }
}


//注册 APNs 成功并上报 DeviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken {
    
    NSString *deviceStr = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    //字符替换
    deviceStr = [deviceStr stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"success get deviceToken: %@", deviceStr);
    
    //极光推送注册 DeviceToken
    [JPUSHService registerDeviceToken:deviceToken];
    //获得注册后的regist_id,此值一般传给后台做推送的标记用,先存储起来
    self.registerid = [JPUSHService registrationID];
    
}


//实现注册 APNs 失败接口(可选)
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    //Optional
    NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error. description);
}


#pragma mark -- UNUserNotificationCenterDelegate
//iOS10 收到通知(本地和远端)

//App处于前台接收通知时
//当app处于前台状态才会走,后台模式下是不会走这里的
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    
    //收到推送的请求
    UNNotificationRequest *request = notification.request;
   
    //收到推送的内容
    UNNotificationContent *content = request.content;
    
    //收到用户的基本信息
    NSDictionary *userInfo = content.userInfo;
    
    //收到推送消息的角标
    NSNumber *badge = content.badge;
    
    //收到推送消息body
    NSString *body = content.body;
    
    //推送消息的声音
    UNNotificationSound *sound = content.sound;
    
    //推送消息的副标题
    NSString *subtitle = content.subtitle;
    
    //推送消息的标题
    NSString *title = content.title;
    
    //本地和远程通知判断
    if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        //远程通知处理Code
        NSLog(@"iOS10 收到远程通知:%@",userInfo);
    }else {
        // 判断为本地通知
        //此处省略一万行需求代码。。。。。。
        NSLog(@"iOS10 收到本地通知:{\nbody:%@,\ntitle:%@,\nsubtitle:%@,\nbadge:%@,\nsound:%@,\nuserInfo:%@\n}",body,title,subtitle,badge,sound,userInfo);
    }
    
    //提醒用户有badge、sound、Alert三种类型选择,需要执行下面的方法
    completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionAlert);
}

//App通知的点击事件
//用户点击消息才会触发,如果用户长按(3DTouch)、弹出Action页面等并不会触发。点击Action的时候会触发!
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
    
    //收到推送的请求
    UNNotificationRequest *request = response.notification.request;
    
    //收到推送的内容
    UNNotificationContent *content = request.content;
    
    //收到用户的基本信息
    NSDictionary *userInfo = content.userInfo;
    
    //收到推送消息的角标
    NSNumber *badge = content.badge;
    
    //收到推送消息body
    NSString *body = content.body;
    
    //推送消息的声音
    UNNotificationSound *sound = content.sound;
    
    //推送消息的副标题
    NSString *subtitle = content.subtitle;
    
    //推送消息的标题
    NSString *title = content.title;
    
    //本地和远程通知判断
    if ([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        //远程通知处理Code
        NSLog(@"iOS10 收到远程通知:%@",userInfo);
    }else {
        // 判断为本地通知
        //此处省略一万行需求代码。。。。。。
        NSLog(@"iOS10 收到本地通知:{\nbody:%@,\ntitle:%@,\nsubtitle:%@,\nbadge:%@,\nsound:%@,\nuserInfo:%@\n}",body,title,subtitle,badge,sound,userInfo);
    }
    
    //UserNotificationsDemo[1765:800117] Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.
    completionHandler(); // 系统要求执行这个方法
}


获得deviceToken需要使用真机进行测试,否则获取不到deviceToken的值。
打印:
success get deviceToken: 95b561f4808f19bf8013401d02af7f4a9ae73062418a692b81592854443e4883



iOS10 之前接收通知的方法

#pragma mark -- iOS10 之前接收到的通知
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    NSLog(@"iOS6及以下系统,收到通知:%@", userInfo);
    //此处省略处理代码。。。。。。
    if (userInfo) {
        if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {// app位于前台通知
            NSLog(@"app位于前台通知(didReceiveRemoteNotification:):%@", userInfo);
        } else {// 切到后台唤起
            NSLog(@"app位于后台通知(didReceiveRemoteNotification:):%@", userInfo);
        }
    }
}

// a. 该回调方法,App杀死后并不执行;
// b. 该回调方法,会与application:didReceiveRemoteNotification:互斥执行;
// c. 该回调方法,会与userNotificationCenter:willPresentNotification:withCompletionHandler:一并执行;
// d. 该回调方法,会与userNotificationCenter:didReceiveNotificationResponse::withCompletionHandler:一并执行。
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    NSLog(@"iOS7及以上系统,收到通知:%@", userInfo);
    //此处省略处理代码。。。。。。
    if (userInfo) {
        if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {// app位于前台通知
            NSLog(@"app位于前台通知(didReceiveRemoteNotification:fetchCompletionHandler:):%@", userInfo);
        } else {// 切到后台唤起
            NSLog(@"app位于后台通知(didReceiveRemoteNotification:fetchCompletionHandler:):%@", userInfo);
        }
    }
    completionHandler(UIBackgroundFetchResultNewData);
}



App将device token发送给 公司的App Server
  只有苹果公司知道device token的生成算法,保证唯一,device token在App重装等情况时会变化,因此为确保device token变化后App仍然能够正常接收服务器端发送的通知,建议每次应用程序启动都重新获得device token,并传给App Server


使用模拟推送工具

  本文只侧重于介绍iOS端对远程推送通知的处理,因此我们把App Server对应的处理过程交给了第三方工具,第三方推送测试工具有很多,如SmartPushPusher等,在这里我们选用Pusher作为测试工具

Pusher的使用步骤说明:
(1)选择p12格式的推送证书;
(2)设置是否为测试环境(默认勾选为测试环境,由于推送证书分为测试推送证书和生产测试证书,并且苹果的APNs也分为测试和生产两套环境,因此Pusher需要手动置顶是否为测试环境);
(3)输入device token;
(4)输入符合苹果要求的推送内容字符串;
(5)当确认手机端设置无误,并且以上4点设置正确时,执行推送。
Pusher推送的消息,以第4点中的示例为例进行测试,手机收到远程推送通知的效果截


iOS 远程通知
消息推送(UserNotifications)秘籍总结(一)
通知详解:iOS 10 UserNotifications API
iOS10通知框架UserNotifications学习及兼容笔记

相关文章

  • 远程推送(US)

    第6阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPh...

  • 远程通知推送教程

    远程通知推送教程 远程通知推送教程

  • 一些项目中可能只需要配置一次的东西吧

    本地推送&远程推送 1.远程推送 推送通知的分类远程推送通知本地推送通知 推送通知作用可以让不在前台运行的App告...

  • 本地推送通知、远程推送通知、激光推送

    title : 本地推送通知、远程推送通知、激光推送category : UI 本地推送通知、远程推送通知、激光...

  • 远程推送 和 本地推送

    一:远程推送 1.远程推送称为APNs 就是远程服务器推送给客户端的通知(需要联网) 2.为什么需要远程推送? 传...

  • iOS开发之远程推送

    远程推送通知 什么是远程推送通知 顾名思义,就是从远程服务器推送给客户端的通知(需要联网)远程推送服务,又称为AP...

  • 远程推送(二): Android 的远程推送

    上篇文章介绍了iOS 远程推送的相关知识,这次来讲讲Android 的远程推送。 Android 远程推送几种常用...

  • 第十四章、消息相关

    说一下远程推送的流程。苹果怎么知道远程推送给哪台设备?又如何知道推送给哪个应用? iOS远程推送通过APNs实现。...

  • 推送通知-远程推送

    iOS远程推送通知 远程推送服务,APNs(apple push notification servers) 所有...

  • iOS远程推送

    远程推送流程概述 iOS远程推送是通过deviceToken进行的,拿到deviceToken需要注册远程通知,注...

网友评论

      本文标题:远程推送(US)

      本文链接:https://www.haomeiwen.com/subject/ocphyctx.html