美文网首页
Unity iOS权限

Unity iOS权限

作者: ShawnWeasley | 来源:发表于2020-08-06 10:15 被阅读0次

    上一篇我们研究了Unity安卓权限被拒绝的情况如何处理,这一篇我们研究一下iOS的权限被用户拒绝的情况下应该如何处理。
    跟安卓一样,本人并不擅长ios编程,仅会设置一些简单的配置,还有调用方法而已。
    不会使用Unity和ios交互的可以先看看以下几篇,都是比较完整的例子:
    https://gameinstitute.qq.com/community/detail/128596
    https://blog.csdn.net/qq_32225289/article/details/82465074
    https://blog.csdn.net/qq_39382771/article/details/81772769
    https://www.jianshu.com/p/1ab65bee6692

    简单概述以下Unity和ios交互,其实就是分为两种,一种是Unity调用ios,另一种是ios调用Unity方法。
    先说第一种Unity调用ios,C#部分其实比较简单,就是用DllImport声明以下方法名比如:

        [DllImport("__Internal")]
        public static extern int OpenAppSettings();
    

    然后再在需要的地方调用声明的这个函数就行

        void Start()
        {
            OpenAppSettings();
        }
    

    大家不熟悉的其实是oc的脚本,这里如果公司有ios开发支持的话就不必看本文了,大部分情况下是只有Unity开发,还得实现某个小功能。
    oc的脚本要让Unity能调到,需要两个文件,一个是.h一个是.mm,如果不会用xcode new一个文件的话,直接去导出的项目中取一个.h和.m文件过来自己重命名就行。
    先说一下.h文件内容,个人理解.h一般是用于声明变量的对应的.m或者.mm再去写方法使用对应的变量。
    本文中使用到的.h就简单示意一下:

    #import<Foundation/Foundation.h>
    @interface Permission:NSObject
    @end
    

    对应的.mm:

    #import "Permission.h"
    #import <AVFoundation/AVFoundation.h>
    #import <AVFoundation/AVCaptureDevice.h>
    @implementation Permission
     extern "C" int OpenAppSettings()
    {
        NSURL*url=[NSURL URLWithString:UIApplicationOpenSettingsURLString];
        if([[UIApplication sharedApplication]canOpenURL:url]){
            [[UIApplication sharedApplication]openURL:url];
        }
    }
    @end
    

    以上方法实现了打开本app的设置界面的功能,也就是上一篇说到的

    AndroidRuntimePermissions.OpenSettings();// 打开本程序的设置界面

    实现的功能是一样的,后续我会整理到一起去。

    使用oc调用Unity就更简单了就一句话:

        UnitySendMessage("Cube","IOSLog","Click");
    

    这里的Cube是场景中物体的名字,IOSLog是物体上脚本的方法名,不需要去声明是哪个类,但方法需要是public的,最后一个参数是传参,支持的类型不多,因此一般用string传参。



    废话说了很多,现在我们来研究下ios的各个权限如何判断是否被用户拒绝了,如果被拒绝,ios是没法再调出来让用户允许的,需要调上述的OpenAppSettings去App设置界面让用户自己打开权限。
    1.首先要判断权限是否被用户允许之前,得呼出权限,即在xcode中修改info界面的设置,根据需要的权限去增加即可,这部分自行百度吧

    info
    也可以手动去修改Info.plist文件,以下图方式打开后可编辑:
    Info.plist
    2.光填写了设置还不行,用户不会收到请求,而会在实际调用的时候才收到请求,因此我们需要去写调用的代码(网络请求除外,网络请求会在启动app的时候即请求,Unity默认会开启网络请求)。因此请求权限和判断权限状态分为两个函数,这里整理了常用的一些权限查询,主要参考于这篇
    首先看看c#是如何调用的,很简单,声明一下,直接调用函数:
        [DllImport("__Internal")]
        public static extern void GetMicrophonePermission();
        [DllImport("__Internal")]
        public static extern void GetMicrophonePermissionState();
        [DllImport("__Internal")]
        public static extern void GetCameraPermission();
        [DllImport("__Internal")]
        public static extern void GetCameraPermissionState();
        [DllImport("__Internal")]
        public static extern void GetPhotoPermission();
        [DllImport("__Internal")]
        public static extern void GetPhotoPermissionState();
        [DllImport("__Internal")]
        public static extern void OpenAppSettings();
    
        public void OnGetMicrophonePermission()
        {
            GetMicrophonePermission();
        }
        public void OnGetMicrophonePermissionState()
        {
            GetMicrophonePermissionState();
        }
        public void OnGetCameraPermission()
        {
            GetCameraPermission();
        }
        public void OnGetCameraPermissionState()
        {
            GetCameraPermissionState();
        }
        public void OnGetPhotoPermission()
        {
            GetPhotoPermission();
        }
        public void OnGetPhotoPermissionState()
        {
            GetPhotoPermissionState();
        }
        public void OnOpenAppSettings()
        {
            OpenAppSettings();
        }
    

    然后是.h文件,也很简单:

    #import<Foundation/Foundation.h>
    @interface Permission:NSObject
    @end
    

    最后是.mm文件:

    #import "Permission.h"
    #import <AVFoundation/AVFoundation.h>
    #import <AVFoundation/AVCaptureDevice.h>
    #import <AssetsLibrary/AssetsLibrary.h>
    #import <Photos/Photos.h>
    #import <CoreTelephony/CTCellularData.h>
    
    @implementation Permission
    
    //首次调用获取联网权限为系统启动即获取,这里不需要写了
    
    //获取联网权限准许状态,此处尝试了一下联网状态判断好像问题很多,暂时先放一下这个
    extern "C" void GetNetworkingPermissionState()
    {
        CTCellularData *cellularData = [[CTCellularData alloc]init];
        CTCellularDataRestrictedState status = cellularData.restrictedState;
         switch (status) {
            case kCTCellularDataRestrictedStateUnknown:
                NSLog(@"蜂窝移动网络状态:未知");
                break;
            case kCTCellularDataRestricted:
                NSLog(@"蜂窝移动网络状态:关闭");
                break;
            case kCTCellularDataNotRestricted:
                NSLog(@"蜂窝移动网络状态:开启");
                break;
            default:
                break;
        }
    }
    
    //首次调用获取麦克风权限
    extern "C" void GetMicrophonePermission()
    {
         [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(bool granted) {
               if (granted) {
                   NSLog(@"%@",@"麦克风准许");
              }else{
                   NSLog(@"%@",@"麦克风不准许");
              }
         }];
    }
    
    //获取麦克风权限准许状态
    extern "C" void GetMicrophonePermissionState()
    {
        AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    
        if (status == AVAuthorizationStatusAuthorized){
            NSLog(@"%@",@"麦克风准许");
        }else{
            NSLog(@"%@",@"麦克风不准许");
        }
    }
    
    //首次调用获取相机权限
    extern "C" void GetCameraPermission()
    {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if (granted) {
                NSLog(@"%@",@"相机准许");
            }else{
                NSLog(@"%@",@"相机不准许");
            }
        }];
    }
    
    //获取相机权限准许状态
    extern "C" void GetCameraPermissionState()
    {
         AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
            if (status == AVAuthorizationStatusAuthorized){
                NSLog(@"%@",@"相机准许");
            }else{
                NSLog(@"%@",@"相机不准许");
            }
    }
    
    //首次调用获取相册权限
    extern "C" void GetPhotoPermission()
    {
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
            if (status == PHAuthorizationStatusAuthorized) {
                NSLog(@"%@",@"相册准许");
            }else{
                NSLog(@"%@",@"相册不准许");
            }
            }];
    }
    
    //获取相册权限准许状态
    extern "C" void GetPhotoPermissionState()
    {
        PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
            if (status == PHAuthorizationStatusAuthorized) {
                NSLog(@"%@",@"相册准许");
            }else{
                NSLog(@"%@",@"相册不准许");
            }
    }
    
    //打开本程序的设置
    extern "C" void OpenAppSettings()
    {
        NSURL*url=[NSURL URLWithString:UIApplicationOpenSettingsURLString];
        if([[UIApplication sharedApplication]canOpenURL:url]){
            if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
            //设备系统为IOS 10.0或者以上的
            [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
            }else{
                //设备系统为IOS 10.0以下的
                    [[UIApplication sharedApplication]openURL:url];
            }
        }
    }
    @end
    

    因为此处用到了#import <Photos/Photos.h>需要手动添加Photos.framework(不需要判断相册权限的小伙伴可以把相册权限判断相关代码删除)。
    添加方式如下:


    添加Photos.framework

    最终我把安卓ios的权限整合到一个插件里了:https://www.jianshu.com/p/26f7293a635c

    相关文章

      网友评论

          本文标题:Unity iOS权限

          本文链接:https://www.haomeiwen.com/subject/ngbvrktx.html