zoukankan      html  css  js  c++  java
  • iOS10 优化APP首次安装网络权限提示方案

    我刚经历了一场末日(停电),特别是在你想写文档的时候。。。

    言归正传,今天的问题是解决iOS10系统下首次按钮APP弹出的网络权限提示所带来了问题以及优化。

    起因



    查了相关文章知道由于大陆工信部出台的新规指出,应用在未经用户允许的前提下,系统不能授予其使用联网、获取定位的功能。Apple在iOS10系统中加入了关于应用使用数据的授权弹窗提示,用户在iOS系统及以上系统中第一次打开应用时,会被要求对于是否授予应用联网权限进行选择。

    问题

    Apple把自己的问题解决了, 但是Apple没有给出官方的获取选择事件的回调,这样就是给开发者挖坑了。
    对于很多开发者习惯于把预加载接口放到AppDelegate的同志就很苦恼了。
    这样会造成配置接口请求失败,首页数据为空的情况,第一次获取DeviceToken失败,添加推送通知失败,第三方初始化失败,以至于导致很多延伸的问题。

    解决

    1.根据CTCellularData类获取网络权限状态以及监听状态改变回调(推荐)

    我就在使用此方法。话不多说上代码,注释很详细;
    添加CoreTelephony系统库,在AppDelegate.m里#import<CoreTelephony/CTCellularData.h>
    1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    2.     // Override point for customization after application launch.  
    3.       
    4.     //1.获取网络权限 根绝权限进行人机交互  
    5.     if (__IPHONE_10_0) {  
    6.         [self networkStatus:application didFinishLaunchingWithOptions:launchOptions];  
    7.     }else {  
    8.         //2.2已经开启网络权限 监听网络状态  
    9.         [self addReachabilityManager:application didFinishLaunchingWithOptions:launchOptions];  
    10.     }  
    11.       
    12.     //初始化window  
    13.     self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];  
    14.     [self.window setBackgroundColor:[UIColor whiteColor]];  
    15.       
    16. //    //创建UI  
    17.     [self createWindowRootWithType:2];  
    18.       
    19.     [self.window makeKeyAndVisible];  
    20.     return YES;  
    21. }  
    22.   
    23. /* 
    24.  CTCellularData在iOS9之前是私有类,权限设置是iOS10开始的,所以App Store审核没有问题 
    25.  获取网络权限状态 
    26.  */  
    27. - (void)networkStatus:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    28.     //2.根据权限执行相应的交互  
    29.     CTCellularData *cellularData = [[CTCellularData alloc] init];  
    30.       
    31.     /* 
    32.      此函数会在网络权限改变时再次调用 
    33.      */  
    34.     cellularData.cellularDataRestrictionDidUpdateNotifier = ^(CTCellularDataRestrictedState state) {  
    35.         switch (state) {  
    36.             case kCTCellularDataRestricted:  
    37.                   
    38.                 NSLog(@"Restricted");  
    39.                 //2.1权限关闭的情况下 再次请求网络数据会弹出设置网络提示  
    40.                 [self getAppInfo];  
    41.                 break;  
    42.             case kCTCellularDataNotRestricted:  
    43.                   
    44.                 NSLog(@"NotRestricted");  
    45.                 //2.2已经开启网络权限 监听网络状态  
    46.                 [self addReachabilityManager:application didFinishLaunchingWithOptions:launchOptions];  
    47. //                [self getInfo_application:application didFinishLaunchingWithOptions:launchOptions];  
    48.                 break;  
    49.             case kCTCellularDataRestrictedStateUnknown:  
    50.                   
    51.                 NSLog(@"Unknown");  
    52.                 //2.3未知情况 (还没有遇到推测是有网络但是连接不正常的情况下)  
    53.                 [self getAppInfo];  
    54.                 break;  
    55.                   
    56.             default:  
    57.                 break;  
    58.         }  
    59.     };  
    60. }  
    61.   
    62. /** 
    63.  实时检查当前网络状态 
    64.  */  
    65. - (void)addReachabilityManager:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    66.     AFNetworkReachabilityManager *afNetworkReachabilityManager = [AFNetworkReachabilityManager sharedManager];  
    67.       
    68.     //这个可以放在需要侦听的页面  
    69.     //    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(afNetworkStatusChanged:) name:AFNetworkingReachabilityDidChangeNotification object:nil];  
    70.     [afNetworkReachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {  
    71.         switch (status) {  
    72.             case AFNetworkReachabilityStatusNotReachable:{  
    73.                 NSLog(@"网络不通:%@",@(status) );  
    74.                 break;  
    75.             }  
    76.             case AFNetworkReachabilityStatusReachableViaWiFi:{  
    77.                 NSLog(@"网络通过WIFI连接:%@",@(status));  
    78.                 if (self.mallConfigModel == nil) {  
    79.                    [self getInfo_application:application didFinishLaunchingWithOptions:launchOptions];  
    80.                 }  
    81.                 break;  
    82.             }  
    83.             case AFNetworkReachabilityStatusReachableViaWWAN:{  
    84.                 NSLog(@"网络通过无线连接:%@",@(status) );  
    85.                 if (self.mallConfigModel == nil) {  
    86.                     [self getInfo_application:application didFinishLaunchingWithOptions:launchOptions];  
    87.                 }  
    88.                 break;  
    89.             }  
    90.             default:  
    91.                 break;  
    92.         }  
    93.     }];  
    94.       
    95.     [afNetworkReachabilityManager startMonitoring];  //开启网络监视器;  
    96. }  
    97.   
    98. - (void)getInfo_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    99.       
    100.     //第三方库初始化  
    101.     [self initValueThirdParty:application didFinishLaunchingWithOptions:launchOptions];  
    102.       
    103. //    //获取初始信息  
    104.     [self initData];  
    105.       
    106.     //添加通知  
    107.     [self addNotification];  
    108. }  



    这样也同时解决了用户如果选择不允许和限制两种情况,在用户没有统一联网的情况下,APP会显示没有网络的UI,重新进入APP会调用在不允许状态下会调用一个测试接口,APP会自动弹出重新选择网络权限以及说明的弹窗,进入设置修改过APP联网权限以后选择回到APP就会触发cellularDataRestrictionDidUpdateNotifier,在回调里进行相应的人机交互就可以了。




    2.延迟请求

    就是把配置请求放到首页VC里,不要放到AppDelegate里,同时监听网络状态(AF,其他第三方等)有个致命性的问题就是获取网络状态会有一定的延迟(亲测),导致很多情况,还有就是要自己处理权限弹框以及对原有代码逻辑要进行修改。

    总结

    这个问题遇到几次了,原来都是用第二种方式进行了一定的优化,这次的APP有一个配置信息接口导致出现问题,写下来作为记录,方法还有很多种,不足的地方还有很多,仅供大家参考。
  • 相关阅读:
    const修饰指针
    C++调用C中编译过的函数要加extern "C"
    linux常用指令(1)
    链式队列实现
    存储类别和类型限定词
    数组,指针和引用
    字符函数和字符串函数
    C/C++编译的程序占用的内存
    结构体1(嵌套使用)
    输入输出函数小结
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/8303261.html
Copyright © 2011-2022 走看看