Unity iOS权限
上一篇我们研究了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.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