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

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

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

(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);
2016-07-12 10:28:55 qq_34195670 阅读数 4430

iOS中通知机制又叫消息机制,其包括两类:一类是本地通知;另一类是推送通知,也叫远程通知。
本地通知是由本地应用触发的,它是基于时间行为的一种通知形式,例如闹钟定时、待办事项提醒,又或者一个应用在一段时候后不使用通常会提示用户使用此应用等都是本地通知。创建一个本地通知通常分为以下几个步骤:

  • 创建UILocalNotification。
  • 设置处理通知的时间fireDate。
  • 配置通知的内容:通知主体、通知声音、图标数字等。
  • 配置通知传递的自定义数据参数userInfo(这一步可选)。
  • 调用通知,可以使用scheduleLocalNotification:按计划调度一个通知,也可以使用presentLocalNotificationNow立即调用通知。

简单实现一个本地通知应用,具体代码如下:
AppDelegate中:

#import "AppDelegate.h"
#import "ViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    _window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    _window.backgroundColor = [UIColor colorWithRed:249/255.0 green:249/255.0 blue:249/255.0 alpha:1.0];

    //设置全局导航条风格和颜色
    [[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:23/255.0 green:180/255.0 blue:237/255.0 alpha:1]];
    [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];


    ViewController *VC = [[ViewController alloc]init];
    _window.rootViewController = VC;

    [_window makeKeyAndVisible];


    //如果已经获得发送通知哦的授权则创建本地通知,否则请求授权(注意:如果不请求授权在设置中是没有对应的通知设置项的,也就是说如果从来没有发送过请求,即使通过设置也打不开消息允许设置)
    if ([[UIApplication sharedApplication]currentUserNotificationSettings].types != UIUserNotificationTypeNone) {
        [self addLocalNotification];
    }else{
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound   categories:nil]];
    }
    return YES;
}
#pragma mark - **************** 调用过用户注册通知方法后执行(也就是调用完registerUserNotificationSettings:方法后执行)
-(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
    if (notificationSettings.types != UIUserNotificationTypeNone) {
        [self addLocalNotification];
    }
}
#pragma mark - **************** 进入前台后设置消息信息
- (void)applicationWillEnterForeground:(UIApplication *)application {
    [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];//进入前台取消应用消息图标
}
#pragma mark - **************** 私有方法
//添加本地通知
-(void)addLocalNotification{
    //定义本地通知对象
    UILocalNotification *notification = [[UILocalNotification alloc]init];
    //设置调用时间
    notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10.0];//通知触发时间,10s之后
    notification.repeatInterval = 2; //通知重复次数

    //设置通知属性
    notification.alertBody = @"你要我怎样---薛之谦,点击查看-----";//通知主体
    notification.applicationIconBadgeNumber = 1;//应用程序右上角显示的未读消息数
    notification.alertAction = @"打开应用";//待机界面的滑动动作提示
    notification.alertLaunchImage = @"Default";//通过点击通知打开应用时的启动图片,这里使用程序启动图片
    //notification.soundName=UILocalNotificationDefaultSoundName;//收到通知时播放的声音,默认消息声音
    notification.soundName=@"msg.caf";//通知声音(需要真机才能听到声音)

    //设置用户信息
    notification.userInfo = @{@"id":@1,@"user":@"XF"};

    //调用通知
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];


}
#pragma mark - **************** 移除本地通知,在不需要此通知时记得移除
-(void)removeNotification{
    [[UIApplication sharedApplication] cancelAllLocalNotifications];
}

@end

注意:
- 在使用通知之前必须注册通知类型,如果用户不允许应用程序发送通知,则以后就无法发送通知,除非用户手动到iOS设置中打开通知。
- 本地通知是有操作系统统一调度的,只有在应用退出到后台或者关闭才能收到通知。
通知的声音是由iOS系统播放的,格式必须是Linear PCM、MA4(IMA/ADPCM)、µLaw、aLaw中的一种,并且播放时间必须在30s内,否则将被系统声音替换,同时自定义声音文件必须放到main boundle中。
- 本地通知的数量是有限制的,最近的本地通知最多只能有64个,超过这个数量将被系统忽略。
- 如果想要移除本地通知可以调用UIApplication的cancelLocalNotification:或cancelAllLocalNotifications移除指定通知或所有通知。

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

2015-09-29 10:13:57 MissYouZhuGe 阅读数 493
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 阅读数 1081

思路介绍

主要考虑以下点

  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 阅读数 208

主要有三种通知:
广播通知(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];
 }

iOS 通知 和 KVO

阅读数 502

监听和通知

阅读数 329

没有更多推荐了,返回首页