美文网首页iOS
iOS 通知详解(远程通知、本地通知)

iOS 通知详解(远程通知、本地通知)

作者: 程序渣渣猿 | 来源:发表于2019-03-10 11:33 被阅读0次

    1. 远程通知

    1.1 开发者账号

    首先要配置开发者账号配置推送证书

    1.2 本地配置

    需要打开本地的推送权限

    推送通知本地配置

    1.3 代码配置

    #import "AppDelegate.h"
    #ifdef NSFoundationVersionNumber_iOS_9_x_Max
    #import <UserNotifications/UserNotifications.h>
    #endif
    
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        
        if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
            //iOS10特有
            UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
            // 必须写代理,不然无法监听通知的接收与点击
            center.delegate = self;
            [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
                if (granted) {
                    // 点击允许
                    NSLog(@"注册成功");
                } else {
                    // 点击不允许
                    NSLog(@"注册失败");
                }
            }];
        }else if ([[UIDevice currentDevice].systemVersion floatValue] >8.0){
            //iOS8 - iOS10
            [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge categories:nil]];
            
        }else if ([[UIDevice currentDevice].systemVersion floatValue] < 8.0) {
            //iOS8系统以下
            [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
        }
        // 注册获得device Token
        [[UIApplication sharedApplication] registerForRemoteNotifications];
        
        return YES;
    }
    
    // 获得Device Token
    - (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
        NSLog(@"%@", [NSString stringWithFormat:@"Device Token: %@", deviceToken]);
    }
    // 获得Device Token失败
    - (void)application:(UIApplication *)application
    didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
        NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
    }
    
    // iOS 10收到通知
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
        NSDictionary * userInfo = notification.request.content.userInfo;
        UNNotificationRequest *request = notification.request; // 收到推送的请求
        UNNotificationContent *content = request.content; // 收到推送的消息内容
        NSNumber *badge = content.badge;  // 推送消息的角标
        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 前台收到远程通知");
            
        }
        else {
            // 判断为本地通知
            NSLog(@"iOS10 前台收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);
        }
        completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
    }
    
    // 通知的点击事件
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
        NSDictionary * userInfo = response.notification.request.content.userInfo;
        UNNotificationRequest *request = response.notification.request; // 收到推送的请求
        UNNotificationContent *content = request.content; // 收到推送的消息内容
        NSNumber *badge = content.badge;  // 推送消息的角标
        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 收到远程通知");
            
        } else {
            // 判断为本地通知
            NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);
        }
        
        // Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.
        completionHandler();  // 系统要求执行这个方法
        
    }
    
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
        
        NSLog(@"iOS7及以上系统,收到通知");
        completionHandler(UIBackgroundFetchResultNewData);
    }
    

    2. 本地通知

    本地通知,无需开发者账号配置什么东西。

    2.1 本地info.plist配置

    在Capabilities中配置

    在Capabilities中配置如下

    2.2 代码配置

    #import "AppDelegate.h"
    #ifdef NSFoundationVersionNumber_iOS_9_x_Max
    #import <UserNotifications/UserNotifications.h>
    #endif
    
    
    /**
     推送权限开关
     
     @return YES:有权限,NO:没权限
     */
    - (BOOL)JX_Device_Permission_NotificationAuth {
        
        if (JX_System_Version >= 8.0f) {
            UIUserNotificationSettings *setting = [[UIApplication sharedApplication] currentUserNotificationSettings];
            if (UIUserNotificationTypeNone == setting.types) {
                return  NO;
            }
        } else {
            UIRemoteNotificationType type = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
            if(UIRemoteNotificationTypeNone == type){
                return  NO;
            }
        }
        return YES;
    }
    
    
    /**
     弹出权限允许
    
     @param permission 权限允许回调
     */
    - (void)JX_Device_Permission_Check_NotificationAuth:(void(^)(BOOL check))permission {
        if (JX_System_Version >= 10.0) {
            [[UNUserNotificationCenter   currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    permission(granted);
                });
            }];
        } else if (JX_System_Version >= 8.0) {
            UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge categories:nil];
            [[UIApplication sharedApplication] registerUserNotificationSettings:setting];
            BOOL auth = [self JX_Device_Permission_NotificationAuth];
            permission(auth);
        } else {
            [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
            BOOL auth = [self JX_Device_Permission_NotificationAuth];
            permission(auth);
        }
    }
    
    /**
     本地推送
     */
    - (void)JX_Category_Notification_Regist_Local {
    
        [self JX_Device_Permission_Check_NotificationAuth:^(BOOL check) {
            if (check) {
                [UNUserNotificationCenter   currentNotificationCenter].delegate = self;
                [JX_Device JX_Device_Permission_Check_NotificationAuth:^(BOOL permission) {
                    
                    if (JX_System_Version >= 10.0) {
                        
                        // 1、创建通知内容,注:这里得用可变类型的UNMutableNotificationContent,否则内容的属性是只读的
                        UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
                        // 标题
                        content.title = @"**";
                        // 次标题
                        content.subtitle = @"****";
                        // 内容
                        content.body = @"*****";
                        
                        // app显示通知数量的角标
                        content.badge = @(1);
                        
                        // 通知的提示声音,这里用的默认的声音
                        content.sound = [UNNotificationSound defaultSound];
                        
                        NSString *path = [[NSBundle mainBundle] pathForResource:@"local" ofType:@"jpg"];
                        UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"imageIndetifier" URL:[NSURL fileURLWithPath:path] options:nil error:nil];
                        
                        // 附件 可以是音频、图片、视频 这里是一张图片
                        content.attachments = @[attachment];
                        
                        // 标识符
                        content.categoryIdentifier = @"categoryIndentifier";
                        
                        // 2、创建通知触发
                        /* 触发器分三种:
                         UNTimeIntervalNotificationTrigger : 在一定时间后触发,如果设置重复的话,timeInterval不能小于60
                         UNCalendarNotificationTrigger : 在某天某时触发,可重复
                         UNLocationNotificationTrigger : 进入或离开某个地理区域时触发
                         */
                        UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
                        
                        // 3、创建通知请求
                        UNNotificationRequest *notificationRequest = [UNNotificationRequest requestWithIdentifier:@"GroupNotification" content:content trigger:trigger];
                        
                        // 4、将请求加入通知中心
                        [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:notificationRequest withCompletionHandler:^(NSError * _Nullable error) {
                            if (error == nil) {
                                NSLog(@"已成功加推送%@",notificationRequest.identifier);
                            }
                        }];
                    } else if (JX_System_Version >= 8.0) {
                        UILocalNotification *notification = [[UILocalNotification alloc] init];
                        // 设置触发通知的时间
                        NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
                        notification.fireDate = fireDate;
                        // 时区
                        notification.timeZone = [NSTimeZone defaultTimeZone];
                        // 通知重复提示的单位,可以是天、周、月
                        notification.repeatInterval = NSCalendarUnitDay;
                        
                        // 通知内容
                        notification.alertBody =  @"****";
                        notification.applicationIconBadgeNumber = 1;
                        // 通知被触发时播放的声音
                        notification.soundName = UILocalNotificationDefaultSoundName;
                        // 通知参数
                        NSDictionary *userDict = [NSDictionary dictionaryWithObject:@"*****" forKey:@"key"];
                        notification.userInfo = userDict;
                        
                        // 执行通知注册
                        [[UIApplication sharedApplication] scheduleLocalNotification:notification];
                    }
                }];
    
            }
        }];
    }
    
    #pragma mark - 收到消息
    
    // iOS 10收到通知(前台收到消息)
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
        // 可以更改远程推送内容
        NSDictionary * userInfo = notification.request.content.userInfo;
        UNNotificationRequest *request = notification.request; // 收到推送的请求
        UNNotificationContent *content = request.content; // 收到推送的消息内容
        NSNumber *badge = content.badge;  // 推送消息的角标
        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 前台收到远程通知");
            
        }
        else {
            // 判断为本地通知
            NSLog(@"iOS10 前台收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);
        }
        completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
    }
    
    // 通知的点击事件(在通知中心点击消息)
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
        NSDictionary * userInfo = response.notification.request.content.userInfo;
        UNNotificationRequest *request = response.notification.request; // 收到推送的请求
        UNNotificationContent *content = request.content; // 收到推送的消息内容
        NSNumber *badge = content.badge;  // 推送消息的角标
        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 收到远程通知");
            
        } else {
            // 判断为本地通知
            NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);
        }
        
        // Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.
        completionHandler();  // 系统要求执行这个方法
        
    }
    
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
        
        NSLog(@"iOS7及以上系统,收到通知");
        completionHandler(UIBackgroundFetchResultNewData);
    }
    
    

    相关文章

      网友评论

        本文标题:iOS 通知详解(远程通知、本地通知)

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