苹果的通知分为本地通知和远程通知,这里主要说的是远程通知

历史介绍

iOS 3 - 引入推送通知UIApplication 的 registerForRemoteNotificationTypes 与 UIApplicationDelegate 的 application(_:didRegisterForRemoteNotificationsWithDeviceToken:),application(_:didReceiveRemoteNotification:)

iOS 4 - 引入本地通知scheduleLocalNotification,presentLocalNotificationNow:,application(_:didReceive:)

iOS 5 - 加入通知中心页面

iOS 6 - 通知中心页面与 iCloud 同步

iOS 7 - 后台静默推送application(_:didReceiveRemoteNotification:fetchCompletionHandle:)

iOS 8 - 重新设计 notification 权限请求,Actionable 通知registerUserNotificationSettings(_:),UIUserNotificationAction 与 UIUserNotificationCategory,application(_:handleActionWithIdentifier:forRemoteNotification:completionHandler:) 等

iOS 9 - Text Input action,基于 HTTP/2 的推送请求UIUserNotificationActionBehavior,全新的 Provider API 等

ios 10 -

  1. 相同的特性使用类似的API(之前的功能API使用方法类似但是还是稍有改变)
  2. 内容扩展(支持附件和展示更多内容)
  3. 本地通知和远程通知操作代码在相同调用路径(合并代理方法)
  4. 简化代理方法
  5. 更好的通知管理(支持通知查、改、删;增强本地通知管理,增加日历与地理位置事件的触发)
  6. 应用内通知展示(之前App在前台的情况下收到通知不会UI展示)
  7. 在Extensions中规划和操作通知(使更新通知内容和删除误发或过期的通知内容成为可能,另一个重要场景为端到端加密)
  8. 引入通知Extensions

1.注册通知

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

  #pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
    CGFloat systemVersion = [[UIDevice currentDevice].systemVersion doubleValue];
    if (systemVersion < 8.0) { //iOS7之前
        [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeNewsstandContentAvailability | UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert];
    } else if(systemVersion < 10.0) { // iOS7-IOS9
#ifdef __IPHONE_8_0
        //        UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init];
        //        action1.identifier = @"action1_identifier";
        //        action1.title=@"确定";
        //        action1.activationMode = UIUserNotificationActivationModeForeground;//当点击的时候启动程序
        //
        //        UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];  //第二按钮
        //        action2.identifier = @"action2_identifier";
        //        action2.title=@"取消";
        //        action2.activationMode = UIUserNotificationActivationModeBackground;//当点击的时候不启动程序,在后台处理
        //        action2.authenticationRequired = YES;//需要解锁才能处理,如果action.activationMode = UIUserNotificationActivationModeForeground;则这个属性被忽略;
        //        action2.destructive = YES;
        //
        //        UIMutableUserNotificationCategory *categorys = [[UIMutableUserNotificationCategory alloc] init];
        //        categorys.identifier = @"category1";//这组动作的唯一标示
        //        [categorys setActions:@[action1,action2] forContext:(UIUserNotificationActionContextDefault)];
        //        NSSet<UIUserNotificationCategory *> set = [NSSet setWithObject:categorys];
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
        [application registerUserNotificationSettings:settings];
        [application registerForRemoteNotifications];
#endif
    } else {
#ifdef __IPHONE_10_0
        UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
        notificationCenter.delegate = self;
        [notificationCenter requestAuthorizationWithOptions:(UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                DLog(@"通知已打开")
            } else {
                DLog(@"通知没有打开,建议用户去通知中心打开通知")
            }
        }];
#endif
        
    }
#pragma clang diagnostic pop
} // ios 10
#pragma mark - UNUserNotificationCenterDelegate
- (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 applicationDidFinishLaunching:.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED
{
    
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken NS_AVAILABLE_IOS(3_0) {
    DLog(@"%@", [NSString stringWithFormat:@"Device Token: %@", deviceToken]);
} - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error NS_AVAILABLE_IOS(3_0) {
    NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
} #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings NS_AVAILABLE_IOS(8_0)
{
    
} // Called when your app has been activated by the user selecting an action from
// a local notification.
// A nil action identifier indicates the default action.
// You should call the completion handler as soon as you've finished handling
// the action.
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
{
    
} // Called when your app has been activated by the user selecting an action from
// a remote notification.
// A nil action identifier indicates the default action.
// You should call the completion handler as soon as you've finished handling
// the action.
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler
{
    
}
#endif

2.接收到通知

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo

{
    DLog(@"iOS6及以下系统,收到通知");
    [self dealRemoteNotification:userInfo];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler NS_AVAILABLE_IOS(7_0)
{
    DLog(@"iOS7收到通知");
    [self dealRemoteNotification:userInfo];
    completionHandler(UIBackgroundFetchResultNewData);
}

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
 
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
     NSDictionary *userInfo = notification.request.content.userInfo;
    [self dealRemoteNotification:userInfo];
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
{
    NSDictionary *userInfo = response.notification.request.content.userInfo;
     [self dealRemoteNotification:userInfo];
}

- (void)dealRemoteNotification:(NSDictionary *) userInfo
{
    NSDictionary *aps = [userInfo objectForKey:@"aps"];
    NSString *alert = [aps objectForKey:@"alert"];
    DLog(@"通知内容:%@", alert);
    DLog(@"收到推送消息:%@", userInfo);
    UIApplicationState state = [UIApplication sharedApplication].applicationState;
    switch (state) {
            
            // app正在前端运行
        case UIApplicationStateActive:
        {
            DLog(@"app active时可以回调此方法,但是手机通知栏没有通知跟声音");
        }
            break;
        case UIApplicationStateBackground:
        {
            DLog(@"UIApplicationStateBackground");
        }
            break;
            
            // app 在后台运行时点击远程通知
        case UIApplicationStateInactive:
        {
            DLog(@"点击通知图标 时点通知启动");
        }
            break;
        default:
            break;
    }
}

3.点击通知

如果APP处于未启动状态,点击通知栏启动APP,此时

      • 若用户直接启动,lauchOptions内无数据;
      • 若由其他应用程序通过openURL:启动,则UIApplicationLaunchOptionsURLKey对应的对象为启动URL(NSURL),UIApplicationLaunchOptionsSourceApplicationKey对应启动的源应用程序的bundle ID (NSString);
      • 若由本地通知启动,则UIApplicationLaunchOptionsLocalNotificationKey对应的是为启动应用程序的的本地通知对象(UILocalNotification);
      • 若由远程通知启动,则UIApplicationLaunchOptionsRemoteNotificationKey对应的是启动应用程序的的远程通知信息userInfo(NSDictionary);
      • 其他key还有UIApplicationLaunchOptionsAnnotationKey,UIApplicationLaunchOptionsLocationKey,
        UIApplicationLaunchOptionsNewsstandDownloadsKey。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *url = [options objectForKey:UIApplicationLaunchOptionsURLKey];
if(url)
{
}
NSString *bundleId = [options objectForKey:UIApplicationLaunchOptionsSourceApplicationKey];
if(bundleId)
{
}
UILocalNotification * localNotify = [options objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if(localNotify)
{
}
NSDictionary * userInfo = [options objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(userInfo)
{
} }

ios 消息通知的更多相关文章

  1. iOS消息通知Notification的用法

    1.发送消息 NSNotification *notification = [NSNotification notificationWithName:@"selectPosition&quo ...

  2. iOS开发-消息通知机制(NSNotification和NSNotificationCenter)

    iOS中委托模式和消息机制基本上开发中用到的比较多,一般最开始页面传值通过委托实现的比较多,类之间的传值用到的比较多,不过委托相对来说只能是一对一,比如说页面A跳转到页面B,页面的B的值改变要映射到页 ...

  3. 消息通知机制(NSNotification和NSNotificationCenter)

    作者:FlyElephant 出处:http://www.cnblogs.com/xiaofeixiang iOS中委托模式和消息机制基本上开发中用到的比较多,一般最开始页面传值通过委托实现的比较多, ...

  4. Unity3D研究院之IOS本地消息通知LocalNotification的使用

    原地址:http://www.xuanyusong.com/archives/2632   现在的游戏里一般都会有本地消息,比如每天定时12点或者下午6点告诉玩家进入游戏领取体力.这种东西没必要服务器 ...

  5. IOS开发-通知与消息机制

    在多数移动应用中不论什么时候都仅仅能有一个应用程序处于活跃状态.假设其它应用此刻发生了一些用户感兴趣的那么通过通知机制就能够告诉用户此时发生的事情. iOS中通知机制又叫消息机制,其包含两类:一类是本 ...

  6. iOS监听模式系列之推送消息通知

    推送通知 和本地通知不同,推送通知是由应用服务提供商发起的,通过苹果的APNs(Apple Push Notification Server)发送到应用客户端.下面是苹果官方关于推送通知的过程示意图: ...

  7. 038改变状态栏的颜色(扩展知识:关于iOS不同版本的消息通知知识)

    效果如下: ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController @e ...

  8. Unity3D研究院之IOS本地消息通知LocalNotification的使用(六十七)

    http://www.xuanyusong.com/archives/2632    现在的游戏里一般都会有本地消息,比如每天定时12点或者下午6点告诉玩家进入游戏领取体力.这种东西没必要服务器去推送 ...

  9. IOS 消息机制(NSNotificationCenter)

    消息机制 NSNotificationCenter 一直都在频繁使用,但是却对其原理不是十分了解.今天就花些时间,把消息机制原理重头到尾好好过一遍. iOS 提供了一种 "同步的" ...

随机推荐

  1. java-图片下载

    图片下载 public static void main(String[] args) { List<String> urlList = new ArrayList<String&g ...

  2. Select Top在七种数据库中的使用方法(包含mysql)

    1. Oracle数据库 SELECT * FROM TABLE1 WHERE ROWNUM<=N 2. Infomix数据库 SELECT FIRST N * FROM TABLE1 3. D ...

  3. New blog

    New blog //域名还没备案_(:з」∠)_

  4. Java 枚举类的基本使用

    枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示. 1.常量的使用       在JDK1.5之前,我们定义常量都是:p ...

  5. BZOJ3083: 遥远的国度

    传送门 BZOJ100题辣(已经无法直视的正确率 树剖板子题,注意和dfs序结合,根据根的变化变换统计的方式即可. //BZOJ 3083 //by Cydiater //2016.10.23 #in ...

  6. <<< Tomcat运行提示The server does not support version 3.0

    导入了一个项目,运行Tomcat出现此错误大致由于当前导入项目服务器不支持J2ee版本 原因是导入项目的Tomcat版本是6.0,Tomcat 6.0仅支持到Servlet 2.5,而此时项目是3.0 ...

  7. 战神Z7 D2安装黑苹果OS X El Capitan 10.11.2

    安装之初状态:两块硬盘,都是MBR格式分区,一块是机械硬盘,安装了WIN7 32位和Linux,一块是SSD,安装的是WIN7 64位与WIN10 64位以前玩过Mavericks,安装的就是在硬盘的 ...

  8. 直接操作 SDL_Overlay YUV叠加上的像素

    根据这篇解码出yuv数据后 海思h264解码库 y,u,v数据全部存进数组内,          IntPtr y = _decodeFrame.pY;                 IntPtr ...

  9. Java数据结构——字典树TRIE

    又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种. 典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计. 它的优点是:利用字符串的公共 ...

  10. Java Web学习笔记3

    今天做了一个实验:Servlet访问WEB-INF目录下的文件notice.html 最后始终不能出现预期的效果,我猜想可能是使用了Tomcat 8版本的原因吧,暂时放下,等以后知识丰富了,再来解决它 ...