iOS

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

2019-03-10  本文已影响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);
}

上一篇下一篇

猜你喜欢

热点阅读