美文网首页iOS
ios10推送(http://www.cnblogs.com/o

ios10推送(http://www.cnblogs.com/o

作者: sll_ | 来源:发表于2017-09-19 17:34 被阅读60次

    3、 推送的注册

    第一步: 导入 #import且要遵守的协议,在Appdelegate.m中。这里需要注意,我们最好写成这种形式(防止低版本找不到头文件出现问题)#ifdef NSFoundationVersionNumber_iOS_9_x_Max#import#endif

    第二步:我们需要在

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中注册通知,代码如下

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [self replyPushNotificationAuthorization:application];

    return YES;

    }

    #pragma mark - 申请通知权限

    // 申请通知权限

    - (void)replyPushNotificationAuthorization:(UIApplication *)application{

    if (IOS10_OR_LATER) {

    //iOS 10 later

    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

    //必须写代理,不然无法监听通知的接收与点击事件

    center.delegate = self;

    [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {

    if (!error && granted) {

    //用户点击允许

    NSLog(@"注册成功");

    }else{

    //用户点击不允许

    NSLog(@"注册失败");

    }

    }];

    // 可以通过 getNotificationSettingsWithCompletionHandler 获取权限设置

    //之前注册推送服务,用户点击了同意还是不同意,以及用户之后又做了怎样的更改我们都无从得知,现在 apple 开放了这个 API,我们可以直接获取到用户的设定信息了。注意UNNotificationSettings是只读对象哦,不能直接修改!

    [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {

    NSLog(@"========%@",settings);

    }];

    }else if (IOS8_OR_LATER){

    //iOS 8 - iOS 10系统

    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];

    [application registerUserNotificationSettings:settings];

    }else{

    //iOS 8.0系统以下

    [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];

    }

    //注册远端消息通知获取device token

    [application registerForRemoteNotifications];

    }

    上面需要注意:1. 必须写代理,不然无法监听通知的接收与点击事件 center.delegate = self;下面是我在项目里定义的宏#define IOS10_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0)#define IOS9_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0)#define IOS8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)#define IOS7_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)2. 之前注册推送服务,用户点击了同意还是不同意,以及用户之后又做了怎样的更改我们都无从得知,现在 apple 开放了这个 API,我们可以直接获取到用户的设定信息了。注意UNNotificationSettings是只读对象哦,不能直接修改!只能通过以下方式获取 [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {            NSLog(@"========%@",settings);  }];打印信息如下:========4、 远端推送需要获取设备的Device Token的方法是没有变的,代码如下

    #pragma  mark - 获取device Token

    //获取DeviceToken成功

    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{

    //解析NSData获取字符串

    //我看网上这部分直接使用下面方法转换为string,你会得到一个nil(别怪我不告诉你哦)

    //错误写法

    //NSString *string = [[NSString alloc] initWithData:deviceToken encoding:NSUTF8StringEncoding];

    //正确写法

    NSString *deviceString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];

    deviceString = [deviceString stringByReplacingOccurrencesOfString:@" " withString:@""];

    NSLog(@"deviceToken===========%@",deviceString);

    }

    //获取DeviceToken失败

    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{

    NSLog(@"[DeviceToken Error]:%@\n",error.description);

    }

    5、这一步吊了,这是iOS 10系统更新时,苹果给了我们2个代理方法来处理通知的接收和点击事件,这两个方法在的协议中,大家可以查看下。@protocol UNUserNotificationCenterDelegate@optional

    // The method will be called on the delegate only if the application is in the foreground. If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. This decision should be based on whether the information in the notification is otherwise visible to the user.

    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);

    // The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from applicationDidFinishLaunching:.

    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED;

    @end

    此外,苹果把本地通知跟远程通知合二为一。区分本地通知跟远程通知的类是UNPushNotificationTrigger.h类中,UNPushNotificationTrigger的类型是新增加的,通过它,我们可以得到一些通知的触发条件 ,解释如下:

    UNPushNotificationTrigger (远程通知) 远程推送的通知类型

    UNTimeIntervalNotificationTrigger (本地通知) 一定时间之后,重复或者不重复推送通知。我们可以设置timeInterval(时间间隔)和repeats(是否重复)。

    UNCalendarNotificationTrigger(本地通知) 一定日期之后,重复或者不重复推送通知 例如,你每天8点推送一个通知,只要dateComponents为8,如果你想每天8点都推送这个通知,只要repeats为YES就可以了。

    UNLocationNotificationTrigger (本地通知)地理位置的一种通知,

    当用户进入或离开一个地理区域来通知。

    现在先提出来,后面我会一一代码演示出每种用法。还是回到两个很吊的代理方法吧

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

    //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]]) {

    //此处省略一万行需求代码。。。。。。

    NSLog(@"iOS10 收到远程通知:%@",userInfo);

    }else {

    // 判断为本地通知

    //此处省略一万行需求代码。。。。。。

    NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);

    }

    // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置

    completionHandler(UNNotificationPresentationOptionBadge|

    UNNotificationPresentationOptionSound|

    UNNotificationPresentationOptionAlert);

    }

    //App通知的点击事件

    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(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]]) {

    NSLog(@"iOS10 收到远程通知:%@",userInfo);

    //此处省略一万行需求代码。。。。。。

    }else {

    // 判断为本地通知

    //此处省略一万行需求代码。。。。。。

    NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);

    }

    //2016-09-27 14:42:16.353978 UserNotificationsDemo[1765:800117] Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.

    completionHandler(); // 系统要求执行这个方法

    }

    需要注意的:

    1.下面这个代理方法,只会是app处于前台状态 前台状态 and 前台状态下才会走,后台模式下是不会走这里的

    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler

    2.下面这个代理方法,只会是用户点击消息才会触发,如果使用户长按(3DTouch)、弹出Action页面等并不会触发。点击Action的时候会触发!

    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler

    3.点击代理最后需要执行:completionHandler(); // 系统要求执行这个方法

    不然会报:

    2016-09-27 14:42:16.353978 UserNotificationsDemo[1765:800117] Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.

    4.不管前台后台状态下。推送消息的横幅都可以展示出来!后台状态不用说,前台时需要在前台代理方法中设置 ,设置如下:

    // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置

    completionHandler(UNNotificationPresentationOptionBadge|

    UNNotificationPresentationOptionSound|

    UNNotificationPresentationOptionAlert);

    6、 iOS 10之前接收通知的兼容方法

    #pragma mark -iOS 10之前收到通知

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

    NSLog(@"iOS6及以下系统,收到通知:%@", userInfo);

    //此处省略一万行需求代码。。。。。。

    }

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    NSLog(@"iOS7及以上系统,收到通知:%@", userInfo);

    completionHandler(UIBackgroundFetchResultNewData);

    //此处省略一万行需求代码。。。。。。

    }

    相关文章

      网友评论

        本文标题:ios10推送(http://www.cnblogs.com/o

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