美文网首页
iOS 本地推送开发记录一

iOS 本地推送开发记录一

作者: Vson2016 | 来源:发表于2018-05-15 10:03 被阅读176次

    前段时间接手到一个关于本地推送的活,还可以设置重复本地推送,把此次记录拆分成两篇,第一篇主要是记录推送的设置,第二篇主要来讲一下如何实现重复推送。

    iOS 本地推送开发记录二

    初始化推送设置(项目支持最低iOS8.0)

    头文件导入,需要增加版本的判断

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

    由于涉及到iOS版本的兼容,需要考虑iOS10以下及iOS8以上的设置

    if (@available(iOS 10.0, *)) {
            //iOS10特有
            UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
           
            // 必须写代理,不然无法监听通知的接收与点击
            center.delegate = self;
            [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
                if (granted) {
                    // 点击允许
                    NSLog(@"注册成功");
                    [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
                        NSLog(@"%@", settings);
                    }];
                } else {
                    // 点击不允许
                    NSLog(@"注册失败");
                }
            }];
        } else {
            UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound) categories:nil];
            [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        }
    

    推送的设置

    if (@available(iOS 10.0, *)) {
            // 使用 UNUserNotificationCenter 来管理通知
            UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
            
            //需创建一个包含待通知内容的 UNMutableNotificationContent 对象,注意不是 UNNotificationContent ,此对象为不可变对象。
            UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
            content.title = title;       
            content.body  = body;
            UNNotificationSound *sound = [UNNotificationSound soundNamed:soundName];
            content.sound = sound;
            content.userInfo = param;
          
            // 在 alertTime 后推送本地推送
            UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger
                                                          triggerWithTimeInterval:timeInterval repeats:NO];
            
            UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:notificationId
                                                                                  content:content trigger:trigger];
            
            //添加推送成功后的处理!
            [center addNotificationRequest:request withCompletionHandler:nil];
        } else {
            NSDate *fireDate = nil;
            if (time > 0) {
                // 定时时间存在,以定时时间为准
                fireDate = [NSDate dateWithTimeIntervalSinceNow:time];
            } else {
                fireDate = [NSDate dateWithTimeIntervalSince1970:dateTime];
            }
            
            // 1.创建通知
            UILocalNotification *localNotification = [[UILocalNotification alloc] init];
    
            // 2.设置通知
            // 设置通知标题
            if (@available(iOS 8.2, *)) {
                localNotification.alertTitle = title ? title : @"";
            }
            // 设置通知显示的内容
            localNotification.alertBody = body ? body : @"";
            // 设置通知的发送时间,单位秒
            localNotification.fireDate = fireDate;
            //收到通知时App icon的角标
            localNotification.applicationIconBadgeNumber = 1;
            //推送是带的声音提醒,设置默认的字段为UILocalNotificationDefaultSoundName
            localNotification.soundName = soundName;
    
            // 3.发送通知
            // 方式一: 根据通知的发送时间(fireDate)发送通知
            NSMutableDictionary *newParam = [NSMutableDictionary dictionaryWithDictionary:param];
            newParam[@"identifier"] = notificationId;
            localNotification.userInfo = newParam;
            [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
        }
    

    推送的处理

    在接收到推送的处理方式上,iOS8和iOS10上有所不同
    iOS8上需要通过UIApplicationDelegate的代理方法如下:

    - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
        NSLog(@"notification:%@", notification);
    }
    

    iOS10上需要通过UNUserNotificationCenterDelegate相关代理方法,iOS10上在应用内收到推送时,可以通过willPresentNotification这个代理方法里面通过completionHandler(0)关闭推送的展示

    //在展示通知前进行处理,即有机会在展示通知前再修改通知内容。
    -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler  API_AVAILABLE(ios(10.0)){
        if (@available(iOS 10.0, *)) {
            if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
                NSLog(@"iOS10 收到远程通知:%@", notification);
            }
            else {
                NSLog(@"iOS10 收到本地通知:%@", notification);
            }
        }
        
        // 避免APP打开的状态下在iOS10+下出现本地推送
        completionHandler(0);
    }
    
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler  API_AVAILABLE(ios(10.0)){
        if (@available(iOS 10.0, *)) {
            if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
                NSLog(@"iOS10 收到远程通知:%@", response);
            }
            else {
                NSLog(@"iOS10 收到本地通知:%@", response);
            }
        }
    }
    

    推送的更新

    iOS8上通过注册时添加一个identifier,在更新时找到这个identifier的推送,并取消,然后重新注册推送即可实现更新。
    iOS10上因为有identifier的存在,所以可以直接复用之前的identifier可以更新成最新的推送

    if (@available(iOS 10.0, *)) {
            // iOS10+  只要重新设置一次 就能完成更新
        } else {
            // 获取所有本地通知数组
            NSArray *localNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;
            for (UILocalNotification *notification in localNotifications)
            {
                NSDictionary *userInfo = notification.userInfo;
                if (userInfo)
                {
                    NSString *identifier = [self getNoticeIdentifierWithId:param[@"id"]];
                    // 如果找到需要取消的通知,则取消
                    if ([identifier isEqualToString:userInfo[@"identifier"]]) {
                        [[UIApplication sharedApplication] cancelLocalNotification:notification];
                        break;
                    }
                }
            }
        }
    

    推送的删除

    iOS8和iOS10上思路都是通过一个identifier来找到之前的推送分别调用自己的取消方法即可,所以如果涉及到修改、删除推送的操作,identifier的设置很重要。

    if (@available(iOS 10.0, *)) {
            [[UNUserNotificationCenter currentNotificationCenter] removePendingNotificationRequestsWithIdentifiers:@[identifier]];
        } else {
            // 获取所有本地通知数组
            NSArray *localNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;
            for (UILocalNotification *notification in localNotifications)
            {
                NSDictionary *userInfo = notification.userInfo;
                if (userInfo)
                {
                    // 如果找到需要取消的通知,则取消
                    if ([identifier isEqualToString:userInfo[@"identifier"]]) {
                        [[UIApplication sharedApplication] cancelLocalNotification:notification];
                        break;
                    }
                }
            }
        }
    

    相关文章

      网友评论

          本文标题:iOS 本地推送开发记录一

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