最近开发的项目需求:访问手机本地相册,且实现多选图片。
网上搜索了一下,实现多选功能手动开发的话较为繁琐,本人对于IOS开发也只是略懂一二,所以决定借助TZImagePickerC框架来实现功能,中文框架,使用起来相对较为方便。框架Git地址:https://github.com/banchichen/TZImagePickerController

Unity和IOS交互
Unity打包IOS端后会生成xcode工程项目,需要借助xcode二次打包进行真机测试或发布。Unity与IOS的交互其实是C#和objectC间的交互。需要在Unity Asset资源的Plugins特殊文件夹下创建oc的头文件和实现文件。然后在C#脚本中调用OC方法

创建一个脚本用来交互,

using System.Runtime.InteropServices;
	
	//oc方法--unity调ios
	[DllImport ("__Internal")]
	private static extern void _iosSelectPhotos();
	
	//回掉方法--ios调oc
	public void PickImageCallBack_Base64(string json_base64)
    {
        Debug.Log($"返回Json为{json_base64}");
        //参数问json格式字符串,转换后为选择的base64格式的图片
    }

[DllImport ("__Internal")]的作用是说明此函数是dll导入的函数,需要也就是从Plugins中创建的oc实体文件中的特殊方法。声明的方法需要用private static extern声明。是多选照片的入口方法,访问Btn调此方法。

PickImageCallBack_Base64方法则是oc实体文件中获取完照片后回调给Unity的方法,具体用法写在oc实体文件内。

脚本写完后在Plugins文件夹下创建如下结构文件:

unity Xcode 调试 iphone ios unity_json


文件后缀一个为.h另一个是.mm

文件内容可以现在编辑,也可以打包出来后用xcode编辑,当然也可以打包出来后用xcode创建,这里选择的是用xcode编辑。

创建完成后进行打包。

unity Xcode 调试 iphone ios unity_json_02


打开Unity-iPhone.xcodeproj(需要安装xcode)

首先将TZImagePickerController导入工程中,Git上下载的TZImagePickerController文件无法直接导入Unity工程,印象中是需要修改所有typeof的地方,不懂ios开发的朋友可以先导入试一下,报错后改一改。不想改的在可以在这里自取。

导入方法直接将TZImagePickerController文件夹拖入左侧预览框项目文件外层。

unity Xcode 调试 iphone ios unity_xcode_03


unity Xcode 调试 iphone ios unity_xcode_04


Finish后即可对IOSAlbumController进行编辑。

在xcode中找到刚才在plugins内创建的文件,路径应该是Libraries—Plugins—IOS下。
先对.h头文件进行编写:

@interface IOSAlbumController:UIViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
@end

再编写.mm文件

#import "TZImagePickerController.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import <Photos/Photos.h>
#import "TZImageManager.h"
#import "IOSAlbumController.h"
@interface IOSAlbumController()<TZImagePickerControllerDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate,UICollectionViewDelegate,UICollectionViewDataSource>{
    
    NSMutableArray * _selectedAssets;
    NSMutableArray * _selectedPhotos;
}
@end
@implementation IOSAlbumController
//访问相册选择图片的的主方法
-(void)pushTZImagePickerController{
    TZImagePickerController *imagePC=[[TZImagePickerController alloc]initWithMaxImagesCount:30 delegate:self];
    imagePC.allowPickingVideo=NO;
    imagePC.allowPickingOriginalPhoto=NO;
    imagePC.selectedAssets=_selectedAssets;
    //以上内容照抄即可,大概就是打开相册选择照片
    //参数photos为选择图片完成后的回调,为UIImage类型的数组。
    [imagePC setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
        
        //将photos数组转换为base64数组
        NSMutableArray *muArray=[NSMutableArray arrayWithCapacity:2];
        
        for (UIImage *object in photos) {
            
            NSString *image64= [self imageToString:object];
            [muArray addObject:image64];
        }
        //因为没有找到UnitySendMessage的重载,第三个参数只能传入 nsstring类型转换成的char数组(貌似是,自己理解的)
        //所以将base64数组转换为json传回unity
        NSDictionary *param=[NSDictionary dictionaryWithObjectsAndKeys:muArray,@"Json", nil];
        
        NSError *error=nil;
        
        NSData *jsonData=[NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:&error];
        NSString *str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        //转换json
        UnitySendMessage("Interact", "PickImageCallBack_Base64", str.UTF8String);
        
        //以下照抄
        [_selectedPhotos removeAllObjects];
        [_selectedAssets removeAllObjects];
        _selectedAssets=[NSMutableArray arrayWithArray:assets];
        _selectedPhotos=[NSMutableArray arrayWithArray:photos];
        
    }];
    [self presentViewController:imagePC animated:YES completion:nil];
}
//image转base64的工具方法
- (NSString *)imageToString:(UIImage *)image {

NSData *imagedata = UIImagePNGRepresentation(image);

NSString *image64 = [imagedata base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

return image64;

}


@end

//unity与ios交互s是通过C语言进行交互,在oc中声明如下C语言代码块
#if defined(__cplusplus)
extern "C"{
#endif

//与在Unity创建脚本时声明的方法名一致
void _iosOpenPhotoLibrary(){
    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){
        IOSAlbumController *app=[[IOSAlbumController alloc]init];
        UIViewController *vc=UnityGetGLViewController();
        [vc.view addSubview: app.view ];
        //前面是打开一个view
        //调用上面的pushTZImagePickerController方法
        [app pushTZImagePickerController];
    }
    else
    {
        //回调回unity的方法,三个参数,
        //第一个,回调脚本(也就是刚才在unity里创建的脚本)所挂载在unity中的GameObject的名字,推荐与脚本同名。
        //第二个,脚本内方法名
        //第三个,char类型数组(好像是,应该差不多)
        UnitySendMessage("Interact", "PickImageCallBack_Base64", (@"").UTF8String);
    }
}

#if defined(__cplusplus)
}
#endif

到此就完成了所有的代码部分,更恶心的地方在xcode的配置,想要真机测试需要apple id和证书下载,真机测试都是免费的,网上有很多帖子,自寻。

写一下我遇到的问题,建议先按照我的问题配置完毕后再打包找错:

1.在TARGETS–General–Frameworks,Libraries,and EmbeddedContent下

添加

CoreLoaction.frameworks;

CoreServices.frameworks;

Photos.frameworks;

ImageIO.frameworks

unity Xcode 调试 iphone ios unity_json_05


2.在TARGETS–Info–Custom IOS Target Properties下,添加Privacy - Photo Library Usage Description键(调用相册时需要询问访问权限,如果需要相机的话也需要加Camera的键,下拉菜单里选择就可以)

unity Xcode 调试 iphone ios unity_xcode_06


unity Xcode 调试 iphone ios unity_xcode_07


3.如果报annot use ‘@try’ with Objective-C exceptions disabled 的错误(最好先打开)

去Targets–BulidSettings – all – combined

Apple Clang-Language-Objective-c

enable objective-c exceptions --yes

unity Xcode 调试 iphone ios unity_json_08

然后就可以进行真机测试,如果还有其他问题可以百度或留言。