zoukankan      html  css  js  c++  java
  • ios 消息通知

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

    历史介绍

    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)
        {
        }
    
    }
  • 相关阅读:
    Swift # Apple Pay集成
    GitHub Top 100 简介
    一些常用算法
    CocoaPods 建立私有仓库
    安装 CocoaPods & Alcatraz
    iOS程序 # 启动过程
    Apache & WebDav 配置(二)
    SVN & Git (二)
    SVN & Git (一)
    poj 3169 Layout (差分约束)
  • 原文地址:https://www.cnblogs.com/wenrisheng/p/6047080.html
Copyright © 2011-2022 走看看