iOS 本地推送开发记录一

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

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;
                }
            }
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352