android安装的时候权限就给了 app安装权限_android安装的时候权限就给了

 

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

 

问题

Apple把自己的问题解决了, 但是Apple没有给出官方的获取选择事件的回调,这样就是给开发者挖坑了。

对于很多开发者习惯于把预加载接口放到AppDelegate的同志就很苦恼了。

这样会造成配置接口请求失败,首页数据为空的情况,第一次获取DeviceToken失败,添加推送通知失败,第三方初始化失败,以至于导致很多延伸的问题。

解决

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

我就在使用此方法。话不多说上代码,注释很详细;

添加CoreTelephony系统库,在AppDelegate.m里#import<CoreTelephony/CTCellularData.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    //1.获取网络权限 根绝权限进行人机交互
    if (__IPHONE_10_0) {
        [self networkStatus:application didFinishLaunchingWithOptions:launchOptions];
    }else {
        //2.2已经开启网络权限 监听网络状态
        [self addReachabilityManager:application didFinishLaunchingWithOptions:launchOptions];
    }
    
    //初始化window
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    [self.window setBackgroundColor:[UIColor whiteColor]];
    
//    //创建UI
    [self createWindowRootWithType:2];
    
    [self.window makeKeyAndVisible];
    return YES;
}

/*
 CTCellularData在iOS9之前是私有类,权限设置是iOS10开始的,所以App Store审核没有问题
 获取网络权限状态
 */
- (void)networkStatus:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //2.根据权限执行相应的交互
    CTCellularData *cellularData = [[CTCellularData alloc] init];
    
    /*
     此函数会在网络权限改变时再次调用
     */
    cellularData.cellularDataRestrictionDidUpdateNotifier = ^(CTCellularDataRestrictedState state) {
        switch (state) {
            case kCTCellularDataRestricted:
                
                NSLog(@"Restricted");
                //2.1权限关闭的情况下 再次请求网络数据会弹出设置网络提示
                [self getAppInfo];
                break;
            case kCTCellularDataNotRestricted:
                
                NSLog(@"NotRestricted");
                //2.2已经开启网络权限 监听网络状态
                [self addReachabilityManager:application didFinishLaunchingWithOptions:launchOptions];
//                [self getInfo_application:application didFinishLaunchingWithOptions:launchOptions];
                break;
            case kCTCellularDataRestrictedStateUnknown:
                
                NSLog(@"Unknown");
                //2.3未知情况 (还没有遇到推测是有网络但是连接不正常的情况下)
                [self getAppInfo];
                break;
                
            default:
                break;
        }
    };
}

/**
 实时检查当前网络状态
 */
- (void)addReachabilityManager:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    AFNetworkReachabilityManager *afNetworkReachabilityManager = [AFNetworkReachabilityManager sharedManager];
    
    //这个可以放在需要侦听的页面
    //    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(afNetworkStatusChanged:) name:AFNetworkingReachabilityDidChangeNotification object:nil];
    [afNetworkReachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
            case AFNetworkReachabilityStatusNotReachable:{
                NSLog(@"网络不通:%@",@(status) );
                break;
            }
            case AFNetworkReachabilityStatusReachableViaWiFi:{
                NSLog(@"网络通过WIFI连接:%@",@(status));
                if (self.mallConfigModel == nil) {
                   [self getInfo_application:application didFinishLaunchingWithOptions:launchOptions];
                }
                break;
            }
            case AFNetworkReachabilityStatusReachableViaWWAN:{
                NSLog(@"网络通过无线连接:%@",@(status) );
                if (self.mallConfigModel == nil) {
                    [self getInfo_application:application didFinishLaunchingWithOptions:launchOptions];
                }
                break;
            }
            default:
                break;
        }
    }];
    
    [afNetworkReachabilityManager startMonitoring];  //开启网络监视器;
}

- (void)getInfo_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    //第三方库初始化
    [self initValueThirdParty:application didFinishLaunchingWithOptions:launchOptions];
    
//    //获取初始信息
    [self initData];
    
    //添加通知
    [self addNotification];
}

 

 

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

2018年08月09日更新

这段时间一直出现微信没有注册的问题,不是必现而且只有线上存在,推荐大家第三方库(特别是需要网络的库)的初始化不需要放到判断网络权限里面,直接初始化。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
        
    //默认更新
    self.appIsUpdate = YES;
    
    //1.获取网络权限 根绝权限进行人机交互
    if (IS_IOS_(10)) {
        [self networkStatus:application didFinishLaunchingWithOptions:launchOptions];
    }else {
        //2.2已经开启网络权限 监听网络状态
        [self addReachabilityManager:application didFinishLaunchingWithOptions:launchOptions];
    }
    
    //初始化第三方库
    [self initValueThirdParty:application didFinishLaunchingWithOptions:launchOptions];
    
    //启动页停留1秒钟。
    [NSThread sleepForTimeInterval:1.0];
    
    //初始化window
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    [self.window setBackgroundColor:[UIColor whiteColor]];
    
    //创建主视图
    if ([DataBase nowUser]) {
        
        [self createWindowRootWithType:2];
    }else {
        
        [self createWindowRootWithType:1];
    }
    
    [self.window makeKeyAndVisible];
    return YES;
}

android安装的时候权限就给了 app安装权限_网络权限提示_02

2.延迟请求

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

 

总结

这个问题遇到几次了,原来都是用第二种方式进行了一定的优化,这次的APP有一个配置信息接口导致出现问题,写下来作为记录,方法还有很多种,不足的地方还有很多,仅供大家参考。