iOS 本地通知(未完待续)

本文详细介绍了iOS中本地通知的两种实现方式:UILocalNotification和UserNotification.framework。从权限申请、通知配置到接收处理,提供了丰富的代码示例和注意事项。

本地通知常用来作为本地提醒,提醒用户待办事项,事物提醒,位置提示等功能 iOS 10.0前,本地通知通知使用的是UILocalNotification,10.0后,苹果推送了专门用户通知提醒的库UserNotificaiton.framework

1.使用 UILocalNotification

iOS8.0之前,通知权限默认开启,可直接使用,但是之后想要使用通知功能,必须提示用户开启通知权限,所以首先需要注册通知, 在didFinishLaunchingWithOptions

if ([[UIDevice currentDevice].systemVersion  doubleValue]>=8.0) {
        // iOS8以后 本地通知必须注册(获取权限)
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
        
        [application registerUserNotificationSettings:settings];
        
        
    }
复制代码

接下来我们需要添加通知触发行为,调用本地通知

1.创建本地通知实例

UILocalNotification * localNoty = [[UILocalNotification alloc]init];
复制代码

2.本地通知属性设置

   /*  本地通知触发时间 */
    localNoty.fireDate =   [NSDate dateWithTimeIntervalSinceNow:4.0];
     /*  通知提示框 */
    localNoty.alertBody = @"提示文本";
    /*  通知提示title  */
    localNoty.alertTitle = @"提示框内容";
    /* 通知提示音 */
    localNoty.soundName = UILocalNotificationDefaultSoundName;
     /* 这里接到本地通知,badge变为1 */
    localNoty.applicationIconBadgeNumber = 1;
    // 设置额外信息,appdelegate中收到通知,可以根据不同的通知的额外信息确定跳转到不同的界面
    localNoty.userInfo = @{@"notifaication":@"我是一条本地推送"};
复制代码

还有其他不常用的属性,如timeZone时区

repeatInterval 多长时间重复一次:一年,一个世纪,一天..

region区域 : 传入中心点和半径就可以设置一个区域(如果进入这个区域或者出来这个区域就发出一个通知)

regionTriggersOnce BOOL 默认为YES, 如果进入这个区域或者出来这个区域 只会发出 一次 通知,以后就不发送了。

alertAction: 设置锁屏状态下本地通知下面的 滑动来 ...字样 默认为滑动来查看 hasAction: alertAction的属性是否生效

alertLaunchImage: 点击通知进入app的过程中显示图片,随便写,如果设置了(不管设置的是什么),都会加载app默认的启动图

alertTitle: 以前项目名称所在的位置的文字: 不设置显示项目名称, 在通知内容上方 soundName: 有通知时的音效 ,UILocalNotificationDefaultSoundName默认声音 可以更改这个声音: 只要将音效导入到工程中,调用localNote.soundName = @"111.waw"

3.调用通知

[[UIApplication sharedApplication] scheduleLocalNotification:localNoty];
复制代码

通知发起后,我们需要接受本地通知,一般在AppDelegate或者其分类中添加实现方法。 一般通知的接受分为三种: 1.前台接收 2.后台未杀死程序进入前台接收 3.程序已经杀死,点击通知消息启动app

针对前两中情况,app的进程仍在运行状态,在didReceiveLocalNotification方法中,添加执行代码,这里可以通过applicationapplicationState属性来判断当前的运行状态,一般执行的操作是app前台运行弹出提示框,后台执行点击通知进入前台直接执行。可以通过notification.userInfo来获取发送通知的userInfo。 针对第三种情况,需要在didFinishLaunchingWithOptions,程序启动过程中添加执行方法

 /* launchOptions: 1.点击图标打开是空的
     2.应用间跳转是有值的
     3.杀死的应用接收到本地通知,也是有值的
     虽然说launchOptions有值,但是他们不同的key有值
 */
  if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) { // 如果这个key有值,代表是杀死的程序接收到本地通知跳转
   
        // 查看launchOptions内容
        UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"本地通知" message:[NSString stringWithFormat:@"%@",launchOptions] delegate:self cancelButtonTitle:@"知道了" otherButtonTitles: nil];
        [alert show];
        NSLog(@"跳转到指定页面");
    }
复制代码

UIApplicationLaunchOptionsLocalNotificationKey这个属性是启动的时候用来判断启动来源的,Keys used to access values in the launch options dictionary passed to the application:willFinishLaunchingWithOptions: and application:didFinishLaunchingWithOptions: methods of the app delegate.

具体说明如下

UIApplicationLaunchOptionsURLKey
// A key indicating that the app was launched so that it could open the specified URL.
UIApplicationLaunchOptionsSourceApplicationKey
// A key indicating that another app requested the launch of your app.
UIApplicationLaunchOptionsRemoteNotificationKey
// A key indicating that a remote notification is available for the app to process.
UIApplicationLaunchOptionsLocalNotificationKey
// A key indicating that the app was launched to handle a local notification.
Deprecated
UIApplicationLaunchOptionsAnnotationKey
// A key indicating that the URL passed to your app contained custom annotation data from the source app.
UIApplicationLaunchOptionsLocationKey
// A key indicating that the app was launched to handle an incoming location event.
UIApplicationLaunchOptionsNewsstandDownloadsKey
// A key indicating that the app was launched to process newly downloaded Newsstand assets.
UIApplicationLaunchOptionsBluetoothCentralsKey
// A key indicating that the app was relaunched to handle Bluetooth-related events.
UIApplicationLaunchOptionsBluetoothPeripheralsKey
// A key indicating that the app should continue actions associated with its Bluetooth peripheral objects.
UIApplicationLaunchOptionsShortcutItemKey
// A key indicating that the app was launched in response to the user selecting a Home screen quick action.
UIApplicationLaunchOptionsUserActivityDictionaryKey
// A key indicating that the data associated with an activity that the user wants to continue.
UIApplicationLaunchOptionsUserActivityTypeKey
// A key indicating the type of user activity that the user wants to continue.
复制代码

类似,我们可以用 NSDictionary *remoteUserInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];来处理远程通知。

需要注意一点,发送多条通知,app的角标会一直累加,所以在启动app的时候didFinishLaunchingWithOptions需要将角标清零

 [application setApplicationIconBadgeNumber:0 ];
复制代码

2.使用UserNotificaiton.framework

相关文档参照:developer.apple.com/documentati… 1.首先,我们需要将UserNotifications引入工程。 然后在AppDelegate.m导入库文件 #import <UserNotifications/UserNotifications.h> 2.授权应用通知权限

 UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound)
                          completionHandler:^(BOOL granted, NSError * _Nullable error) {
                              if(!error)
                              {
                                  NSLog(@"@授权成功");
                              }
                          }];
复制代码

之前注册推送服务,ios 8 及之前使用了不同的 API,并且返回结果也不同。现在 apple 不仅统一了这个 API,而且我们可以获取到用户更加详细的设定了。

   [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
        NSLog(@"%@",settings);
    }];
复制代码

打印结果如下: <UNNotificationSettings: 0x60400009cd40; authorizationStatus: Authorized, notificationCenterSetting: Enabled, soundSetting: Enabled, badgeSetting: Enabled, lockScreenSetting: Enabled, carPlaySetting: NotSupported, alertSetting: Enabled, alertStyle: Banner>

如果需要注册远程通知:

[[UIApplication sharedApplication] registerForRemoteNotifications];
复制代码

2.发送本地通知 UserNotificaiton发送本地通知需要使用UNNotificationRequest类,实例方法如下

+ (instancetype)requestWithIdentifier:(NSString *)identifier content:(UNNotificationContent *)content trigger:(nullable UNNotificationTrigger *)trigger;
复制代码

所以我们需要分别设定 UNNotificationContentUNNotificationTrigger并设置一个标识符。

UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.title = @"this is Notifications";
    content.subtitle = @"本地通知";
    content.body = @"推送一条本地通知";
    content.badge = @1;
    content.userInfo = @{@"type":@"this is a userNotification"};
复制代码

Triggers

又是一个新的功能,有三种

  • UNTimeIntervalNotificationTrigger

  • UNCalendarNotificationTrigger

  • UNLocationNotificationTrigger 他们的使用方式如下:

     //8s后提醒
    UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:8 repeats:NO];
    
    //每小时重复 1 次喊我喝水
    UNTimeIntervalNotificationTrigger *trigger2 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:3600 repeats:YES];
    
    //每周一早上 8:00 提醒我给起床
    NSDateComponents *components = [[NSDateComponents alloc] init];
    components.weekday = 2;
    components.hour = 8;
    UNCalendarNotificationTrigger *trigger3 = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];
    
    //需导入定位库   #import <CoreLocation/CoreLocation.h>
    //一到距离(123.333, 123.344)点20米就喊我下车
    CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:CLLocationCoordinate2DMake(123.333, 123.344) radius:20 identifier:@"regionidentifier"];
  
    UNLocationNotificationTrigger *trigger4 = [UNLocationNotificationTrigger triggerWithRegion:region repeats:NO];
复制代码

发出通知

NSString *requestIdentifier = @"sampleRequest";

 UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier
 content:content  trigger:trigger1];
 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {

    }];
复制代码

3.接收本地通知并处理。 与LocalNotificationL类似,有三种情况

(1).前台接收

(2).后台未杀死程序进入前台接收

(3).程序已经杀死,点击通知消息启动app 需要遵循UNUserNotificationCenterDelegate代理协议方法

center.delegate = self;
复制代码

通过以下两个UNUserNotificationCenterDelegate的方法实现

 // The method will be called on the delegate only if the application is in the foreground. If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. This decision should be based on whether the information in the notification is otherwise visible to the user.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);

// The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from application:didFinishLaunchingWithOptions:.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED;
复制代码

实现如下:

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
    NSLog(@"willPresentNotification:%@",notification.request.content.title);
    
    // 这里真实需要处理交互的地方
    // 获取通知所带的数据
    NSString *apsContent = [notification.request.content.userInfo objectForKey:@"type"];
    NSLog(@"%@",apsContent);
    
    
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
    //在没有启动本App(包括后台运行中)时,收到服务器推送消息,下拉消息会有快捷回复的按钮,点击按钮后调用的方法,根据identifier来判断点击的哪个按钮
    NSString *apsContent = [response.notification.request.content.userInfo objectForKey:@"type"];
    NSLog(@"didReceiveNotificationResponse:%@",response.notification.request.content.title);
    NSLog(@"%@",apsContent);

}
复制代码

我们可已通过removeIdentifier删除计划的推送事件:

[center removePendingNotificationRequestsWithIdentifiers:@[requestIdentifier]];
复制代码

如果我们需要更新推送,可以通过 addNotificationRequest: 方法,在 Identifier 不变的情况下重新添加,就可以刷新原有的推送。

转载于:https://juejin.im/post/5a4c44def265da430b7b9f92

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值