2017-03-26 14:17:29 MLtianya 阅读数 325

这里主要介绍 本地通知 的添加以及移除方法

同时还介绍了查询是否开启通知权限的方法

(1).iOS10 以后 本地推送 使用 UNUserNotificationCenter 来管理通知

(2).iOS7、8本地推送使用 UILocalNotification 来管理通知

但是iOS8 需要授权才能使用本地通知
下面看代码:
iOS10以前的代码

1. 添加 通知

 + (void)registerLocalNotificationInOldWay:(NSString *)alertTime {

    UILocalNotification *notification = [[UILocalNotification alloc] init];

    // 设置触发通知的时间
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"ss";
    NSDate *fireDate = [formatter dateFromString:alertTime];
    NSLog(@"fireDate=%@",fireDate);
    // 设置通知的时间,可以使固定的时间,也可以是从添加开始之后的多长时间
    //第一种
     //    notification.fireDate = fireDate;
     //第二种
   notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
    // 时区
    notification.timeZone = [NSTimeZone defaultTimeZone];
    // 设置重复的间隔(最小重复间隔是每分钟)
    notification.repeatInterval = NSCalendarUnitMinute;

    // 通知内容
    notification.alertBody =  @"今天不要忘记签到看书哦~";
    notification.applicationIconBadgeNumber = 1;// 需要在App icon上显示的未读通知数(设置为1时,多个通知未读,系统会自动加1,如果不需要显示未读数,这里可以设置0)
    // 通知被触发时播放的声音
    notification.soundName = UILocalNotificationDefaultSoundName;
    // 通知参数(添加通知的参数,以便之后找到这个通知)
    NSDictionary *userDict = [NSDictionary dictionaryWithObject:@"localNotification" forKey:@"localNotification"];
    notification.userInfo = userDict;

    // ios8后,需要添加这个注册,才能得到授权
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIUserNotificationType type =  UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type
                                                                                 categories:nil];
        UIUserNotificationSettings *notificationSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
        if (notificationSettings.types == UIUserNotificationTypeNone) {
            [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        }

        // 通知重复提示的单位,可以是天、周、月
        notification.repeatInterval = NSCalendarUnitMinute;
    } else {
        // 通知重复提示的单位,可以是天、周、月
        notification.repeatInterval = NSCalendarUnitMinute;
    }

    // 执行通知注册
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];
}

iOS10 添加本地通知

// 使用 UNUserNotificationCenter 来管理通知
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];

//需创建一个包含待通知内容的 UNMutableNotificationContent 对象,注意不是 UNNotificationContent ,此对象为不可变对象。
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:@"提示" arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:@"今天不要忘记签到看书哦~"
                                                     arguments:nil];
content.sound = [UNNotificationSound defaultSound];
// 在 alertTime 后推送本地推送
// 同样的这里也可以添加固定时间 和 添加之后的多长时间
// 1.固定时间 每个小时的10分10秒发送通知(当然先添加小时,几月几日都可以,每周的第几天也可以)
NSDateComponents *components = [[NSDateComponents alloc] init];
components.minute = 10;
components.second = 10;
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];
// 2,添加后的多长时间发送通知
// UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];

// localNotification 通知的标识(同样的查询通知的时候使用)
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"localNotification"
                                                                      content:content trigger:trigger];

//添加推送成功后的处理!
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {

}];

2.移除通知

// 判断是 iOS 10以后的
 if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0)) {
        UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
        [center removePendingNotificationRequestsWithIdentifiers:[NSArray arrayWithObjects:@"localNotification", nil]];
    }else{
        // 设置要移除的通知id
        NSString *notificationId = @"localNotification";
        NSArray *notifiArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
        for (UILocalNotification *local in notifiArray) {
            //将来可以根据UserInfo的值,来查看这个是否是你想要删除的通知
            if ([[local.userInfo objectForKey:@"localNotification"] isEqualToString:notificationId]) {
                //删除单个通知
                [[UIApplication sharedApplication]cancelLocalNotification:local];
            }
        }

3.查询是否开启通知权限

// 由于 iOS10 是在block中会掉的 所以这里需要一个block 下面有block的声明方法
+ (void)isOpenMessageNotificationServiceWithBlock:(CheckBlock)checkBlock
{
 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
        [[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *settings) {
            if (checkBlock) {
                returnBlock(settings.authorizationStatus == UNAuthorizationStatusAuthorized);
            }
        }];
    }else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0){
        checkBlock([[UIApplication sharedApplication] isRegisteredForRemoteNotifications]);
    }else{
        UIRemoteNotificationType type = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
        if (checkBlock) {
            checkBlock(type != UIRemoteNotificationTypeNone);
        }
    }
}

4.声明block

typedef void(^CheckBlock)(BOOL isOpen);
2015-09-29 10:13:57 MissYouZhuGe 阅读数 503
iOS本地通知注册和取消,可以实现很多本地需要的提醒功能,如闹钟,提醒事项等,很方便,用法也很简单。
- (void)registerLocalNotification:(CGFloat)alertTime message:(NSString *)msg key:(NSString *)key
{
    UILocalNotification *notification = [[UILocalNotification alloc] init];

    // 时区
    notification.timeZone = [NSTimeZone localTimeZone];

    // 通知触发时间
    notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:alertTime];

    // 通知内容
    notification.alertBody = msg;
    notification.applicationIconBadgeNumber = [[[UIApplication sharedApplication] scheduledLocalNotifications] count] + 1;

    // 通知被触发时播放的声音
    notification.soundName = UILocalNotificationDefaultSoundName;

    // 通知参数
     NSDictionary *userDict = [NSDictionary dictionaryWithObject:msg forKey:key];
     notification.userInfo = userDict;

    // ios8后,需要添加这个注册,才能得到授权
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIUserNotificationType type =  UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    }
    // 通知重复提示的单位,可以是天、周、月
    notification.repeatInterval = kCFCalendarUnitEra;

    // 执行通知注册
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];
}

// 取消某个本地推送通知
- (void)cancelLocalNotificationWithKey:(NSString *)key {
    // 获取所有本地通知数组
    NSArray *localNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;

    for (UILocalNotification *notification in localNotifications) {
        NSDictionary *userInfo = notification.userInfo;
        if (userInfo) {
            // 根据设置通知参数时指定的key来获取通知参数
            NSString *info = userInfo[key];

            // 如果找到需要取消的通知,则取消
            if (info != nil) {
                [[UIApplication sharedApplication] cancelLocalNotification:notification];
                break;
            }
        }
    }
}

希望对大家有所帮助。

2015-10-05 15:12:32 Lotheve 阅读数 1089

思路介绍

主要考虑以下点

  1. 如何设置推送(包括推送内容、推送时间、推送周期等)
  2. 如何接收推送 考虑3种情况
    1. app在前台运行
    2. app未关闭,在后台运行
    3. app关闭
  3. 接收到推送后如何响应(主要的用户交互在这里)
  4. 如何移除本地推送

代码说明

注册本地通知

/*!
 *  注册本地通知
 */
+ (void)registerLocalNotification{
    //初始化本地通知
    UILocalNotification *localNotification = [[UILocalNotification alloc]init];
    //触发通知时间
    localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:6]; //6s后触发通知
    //时区
    localNotification.timeZone = [NSTimeZone defaultTimeZone];
    //触发通知后弹出警告框中显示的内容
    localNotification.alertBody = @"这是一个本地通知";
    //触发通知时的声音(这里使用系统的声音)
    localNotification.soundName = UILocalNotificationDefaultSoundName;

    //设置在app icon右上角显示的未读标识
    NSInteger badgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber;
    localNotification.applicationIconBadgeNumber = badgeNumber+1;

    //设置通知的用户信息(可以用于移除通知,也可以传其他的值到获取通知的方法中)
    localNotification.userInfo = @{@"key":@"notification1"};

    //ios8后,需要先注册通知类型,才能得到授权
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIUserNotificationType type =  UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        //触发通知的频率(是一个枚举变量,可以设置每分、每时、每天等)
        localNotification.repeatInterval = NSCalendarUnitDay;
    } else {
        //触发通知的频率(是一个枚举变量,可以设置每分、每时、每天等)
        localNotification.repeatInterval = NSDayCalendarUnit;
    }

    //执行通知计划
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}

不同情况下本地推送的接收及响应

/*!
 *  接收到本地通知时的回调(有两种情况会在这里接收到通知推送。一、app在前台运行;二、app在后台运行,用户点击通知栏通知切回前台。注意:如果app在后台运行,用户接收到推送的通知,不是点击通知,而是点击app图标切回到app,是不会触发这个回调的)
 */
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
    NSLog(@"----------------%@",notification);

    //接收到通知后的交互
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:nil message:notification.alertBody delegate:nil cancelButtonTitle:@"确定" otherButtonTitles: nil];
    [alert show];

    //更新未读标识
    NSInteger badge = [UIApplication sharedApplication].applicationIconBadgeNumber;
    NSLog(@"%zi",badge);
    badge--;
    badge = badge >= 0 ? badge : 0;
    [UIApplication sharedApplication].applicationIconBadgeNumber = badge;

    //根据需要移除通知
    [ViewController removeLocalNotificationForName:@"notification1"];

    // do something else
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    //当app在关闭情况下接收到本地推送通知时,点击通知栏对应的通知启动app会调用此方法,此时通过langchOptions参数可以获取到记载了本地通知的相关信息。如果是通过点击app图标启动app,也会调用这个方法,但是launchOptions通过UIApplicationLaunchOptionsLocalNotificationKey关键字获取到的本地通知信息为空。
    UILocalNotification *localNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsLocalNotificationKey];
    if (localNotification) {

        //获取本地通知详细信息
        NSDictionary *userInfo = localNotification.userInfo;
        //通过信息判断为哪条本地通知, 做出相应回应
        NSString *key = [userInfo objectForKey:@"key"];
        if ([key isEqualToString:@"notification1"]) {

            //更新未读标识
            NSInteger badge = [UIApplication sharedApplication].applicationIconBadgeNumber;
            badge--;
            badge = badge >= 0 ? badge : 0;
            [UIApplication sharedApplication].applicationIconBadgeNumber = badge;

            //接收到通知后的交互
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:nil message:@"Mark" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles: nil];
            [alert show];

            //根据需要移除通知
            [ViewController removeLocalNotificationForName:@"notification1"];

            // do something else
        }
    }
    return YES;
}

移除本地推送

/*!
 *  移除本地通知
 *  [[UIApplication sharedApplication] cancelAllLocalNotifications]; 可以移除所有本地推送
 *
 *  @param notificationName 本地通知自定义的名字标识
 */
+ (void)removeLocalNotificationForName:(NSString *)notificationName{
    if (!notificationName) {
        return;
    }
    //获取所有本地通知
    NSArray *arrayNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;
    //遍历所有通知 根据名字标识移除指定通知
    for (UILocalNotification *localNotification in arrayNotifications) {
        NSDictionary *dic = localNotification.userInfo;
        if ([[dic objectForKey:@"key"] isEqualToString:notificationName]) {
            [[UIApplication sharedApplication] cancelLocalNotification:localNotification];
            NSLog(@"通知 %@ 已移除",notificationName);
        }
    }
}

参考文档:
ios推送:本地通知UILocalNotification
本地推送通知UILocalNotification
iOS本地推送(本地通知)

2016-01-25 15:35:00 KarenMiao 阅读数 218

主要有三种通知:
广播通知(broad notification)
本地通知(local notification)
推送通知即远程通知(push notification)

广播通知
将要接受通知的对象需要向通知中(NSNotificationCenter) 注册,当投放对象投送通知给通知中心时,通知中心就会把通知广播给注册过的接受者,当观察者不再观察时,则移除

  • 发布通知postNotification…
  • 添加观察者addObserver…
  • 不再关注removeObserver

本地通知

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;



    //本地通知
    UILocalNotification *notification=[[UILocalNotification alloc] init];
    if (notification!=nil) {
        [[UIApplication sharedApplication] cancelAllLocalNotifications];

        NSDate *now=[NSDate new];
        notification.fireDate=[now dateByAddingTimeInterval:10]; //触发通知的时间
        notification.repeatInterval = kCFCalendarUnitMinute;     //循环次数,kCFCalendarUnitWeekday一周一次

        notification.timeZone=[NSTimeZone defaultTimeZone];
        notification.soundName = UILocalNotificationDefaultSoundName;
        notification.alertBody=@"哈哈哈哈哈";               //若alertBody不为nil,则显示alert

        //在模拟器上暂时还没有测试出以下两个属性的作用
        notification.alertAction = @"打开";  //显示alert右侧提示按钮
        notification.hasAction = YES;       //默认为YES,是否显示额外的按钮,为no时alertAction消失

        notification.applicationIconBadgeNumber = 1; //设置app图标右上角的数字

        //下面设置本地通知发送的消息,这个消息可以接受
        NSDictionary* infoDic = [NSDictionary dictionaryWithObject:@"value" forKey:@"key"];
        notification.userInfo = infoDic;
        //发送通知
        [[UIApplication sharedApplication] scheduleLocalNotification:notification];
    }


    [self.window makeKeyAndVisible];
    return YES;
}

远程通知
远程推送服务,APNs(apple push notification servers)
所有的苹果设备,在联网状态下,都会与苹果的服务器建立长连接
过程:

  • 客户端的app需要将用户的UDID和app的bundleID发送给apns服务器,进行注册,apns将加密后的device Token返回给app
  • app获得device Token后,上传到公司服务器
  • 当需要推送通知时,公司服务器会将推送内容和device Token一起发给apns服务器

PS:

例:保证self定义了aWindowBecameMain:方法。而对于一个任意的观察者observer,不能保证其对应的selector有aWindowBecameMain:,可采用[observer respondsToSelector:@selector(aWindowBecameMain:)]] 进行检查。所以完整的添加观察者过程为:if([observer respondsToSelector:@selector(aWindowBecameMain:)]) {
 [[NSNotificationCenter defaultCenter] addObserver:observer selector:@selector(aWindowBecameMain:) name:NSWindowDidBecomeMainNotification object:nil];
 }

2016-06-02 17:56:14 ZhiDaiHuaKai 阅读数 348

通知中心(基于观察者模式)属于Foundation框架;
通知(本地通知、推送通知)属于UIKit框架;

通知中心是iOS程序内部间的一种消息广播机制,主要解决程序内部不同对象间解耦;基于观察者模式,不能跨应用程序进程通信,通知中心接收到消息之后会以广播的形式通知所有监听者。通知中心的本质是监听一个字符串。移除通知一般在监听器销毁之前取消注册。

当应用程序启动后、进入后台、进入前台、获得焦点、失去焦点、窗口大小改变、隐藏等都会发送通知。

通知中心是同步的,目的是为了保证所有的监听者都对通知做出响应。

通知中心是一种低耦合设计,和代理模式有类似之处。通知中心和代理的区别:

  1. 代理是一对一的,可通过代理指针调用selector方法
  2. 通知中心是一对多的,只要接收到消息,会以广播的形式,通知所有的监听者
  3. 通知中心发布通知的对象不需要知道谁是监听者,发布对象和监听者之间的耦合度很低
  4. 监听者需要知道通知的名词字符串,若发布者有传递userInfo字典,监听者同时需要知道字典的键名
  5. 通知监听方法不能有返回值
  6. 代理可以有返回值
  7. 代理的代码布局结构较清晰,不像通知(监听)一样随处都可添加监听
没有更多推荐了,返回首页