刘宏立博客

iOS原生工程接入Unity导出的Xcode工程

提示:
2017年7月13日更新

相关文章:
1>. IL2CPP 构建大小优化

前言:项目iOS原生工程是LBS的开发,在iOS原生和Unity的Xcode工程进行整合方面,网上多是将Unity的Xcode工程导入到自己的原生项目中,而对于iOS原生工程接入Unity导出的Xcode工程几乎找不到,虽然相对更简单.第一次整合iOS-Unity项目,会报很多错误,报到让自己怀疑人生.还好,最终找到了一个很简单的整合流程.项目要求不一样,过程也许不同,不过,万一对你有帮助,就会省去很多时间.文章旨在帮助还在iOS-Unity整合的路上苦苦挣扎的程序员脱离错误的红海,同时详细记录自己的实现步骤.

注意:在选择 Mono2x 和 IL2CPP 时操作步骤稍有不同: Mono2x 导出工程后只需要在 build settings 将 HEADER_SEARCH_PATHS 添加 $(inherited),其余不可以修改,否则可能会报错误;在 IL2CPP 设置状态下,可以将警告(在下文)内容全部在 build settings 中对应设置.
前提条件: 1. 工程是以Unity工程为主,如游戏的开发. 2. 我使用了cocoapods,如果不知道,这个将是你填的一个天坑.
详细步骤放入下:为了展现更直接,主要以截图呈现
1.Unity导出Xcode工程前的设置1:

001UnityBuildSettings.png
2.Unity导出Xcode工程前的设置2:

002UnitySetting.png

3.Unity导出Xcode工程前的设置3:CompanyName和ProductName根据自己项目填写

003UnityPlayerSetting1.png

4.Unity导出Xcode工程前的设置4:
注意:最好用你之前原生项目的Bundle Identifier,因为,你的项目中也许用到了第三方,在第三方的后台已经填写了Bundle Identifier

004UnityPlayerSettings2.png

5.Unity导出Xcode工程前的设置5:最好把这一项选上
004UnityPlayerSettings3.png

6.Unity导出Xcode工程前的设置6:如果你的Unity工程没有不兼容的地方,应该很顺利导出,如果出现Unity的代码或资源不兼容,赶快找相关负责人进行解决,我的就出现了代码和图片资源的报错
005UnitySetting.png

7.Unity的Xcode工程导出成功后,打开终端,切换到对应的根目录:如图中的client
007TerminalChangePath.png

8.pod init 创建podfile文件
008TerminalPodInit.png

9.打开podfile文件,按格式写入需要pod的第三方库,我用到的第三方库如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
platform :ios, '8.0'
target 'Unity-iPhone' do
pod 'AMap3DMap'
pod 'AMapLocation'
pod 'AMapSearch'
pod 'Masonry'
pod 'pop'
pod 'AFNetworking'
pod 'YYModel'
end

009TerminalThirdName.png

10.打开终端,pod install,完成之后会看到如下图所示的黄色字体的警告: Smart quotes的警告是因为我们操作podfile文件用的是文本格式,如果想去掉这个警告,可以使用sublime或Xcode操作podfile文件,保证podfile文件的单引号是英文格式的.
特别重要的是以下Release(一定要设置Release状态,其它状态可以设置也可以不设置) 状态下的四个警告,其中”HEADER_SEARCH_PATHS”最重要,这个一定要在BuildSettings中添加一个$(inherited)
依次在BuildSettings中找到:Other_CFLAGS和OTHER_LDFLAGS,并分别添加$(inherited)
如果添加这三项后没有报错,就可以了,但是如果依然有报错,就将BuildSettings中的ARCHS也添加$(inherited),之后如果再有报错,就要看报错内容具体是什么.

010TeiminalAlertInfo..png

11.打开白色的workspace(工作空间)文件,运行,看是否报错,我运行的时候报错是我的iPhone版本低,将Xcode运行的手机系统版本设置降低到小于等于你的设备的iOS系统版本即可.

011XcodeProject.png

012XcodeAlert.png
12.另一个错误是没有选择开发team,如下图选择即可

013XcodeSetting.png

13.这个错误是因为在Unity原文件中写了必须要实现的方法(这个根据你的项目而定该实现哪种方法),我的将写好的代码文件直接拖进Xcode中即可.

014XcodeError.png

14.需要解决上一步的错误问文件:(文件根据具体工程的调用方法而定)

015XcodeFile.png

15.设置Xcode Build Settings,此处是为了解决Unity导出的 Xcode 工程和 cocoapods 的配置不兼容的问题,就是上面 pod install 第三方库的时候报的警告问题: 如下图,我想导入 Masonry的头文件,但是不能导入,此时虽然我们的第三方框架安装了,但是还无法使用

016XcodeSettings.png

16.将项目设置为Release状态下:

016.1XcodeEditScheme01.png

016.2XcodeSchemeRelease.png
17.在Build Settings下设置 HEADER_SEARCH_PATHS,添加一项并设置为:$(inherited)

017XcodeBuildSettings.png

018XcodeThirdLib.png

  1. 并依次在Build Settings下设置: OTHER_CFLAGS, OTHER_LDFLAGS;并且都把值设置为:$(inherited)

19.将自己的项目拖入到 Xcode导出的工程,注意只需要将根目录下的那个你写代码的文件夹拖进去即可,里面包含了你写的所有代码:如下图所示

019XcodeMapFile.png

20.这一步不同的项目会有不同,目的是跳转到我们用Xcode写的原生控制器中,主要代码如下:

1
2
3
4
5
if (_mapVC == nil) {
_mapVC = [[BTMapVC alloc]init];
}
UnityPause(true);
[UnityGetGLViewController() presentViewController:_mapVC animated:NO completion:nil];

如下图所示:

020XcodeUnityMapVC.png

21.发现一大堆错误,是因为我用了 pch 文件,而将 pch 文件拖入到新工程里,此时需要设置 pch 文件路径,这里我是将 Unity 导出的 Xcode 工程的 pch 文件里的内容复制到原生的 pch 文件里,然后再设置原生 pch 文件的路径,你也可以尝试将原生工程的 pch 文件内容复制到 Unity 导出工程的 pch 文件里:如下图

021XcodeError.png

022XcodePch.png

023XcodePch.png

22.我们将原生工程文件拖进 Unity 导出的 Xcode 工程后,一个工程就出现了两个main文件,一个是 main.m,一个是 main.mm,会报错如下图,因为我们是以 Unity 为主的项目,因此删除掉 main.m

024XcodeError.png

23.如果出现以下错误可能是因为你没有将 Unity导出的 Xcode 工程的 pch 文件内容复制到你设置的 pch 文件里,报错如下图

025XcodeError.png

026XcodePch.png

24.我开发的原生项目是LBS,跳转的时候会进行定位,需要设置几个选项,如果不设置跳转的时候会崩溃:

027XcodeBreakPoint.png
设置Background Mode,并在 Info.plist 设置: NSLocationWhenInUseUsageDescription或者 NSLocationAlwaysUsageDescription
28XcodeSetting.png

infoPlist定位权限设置.png

25.在跳转到原生工程界面的时候要将 Unity 暂停,在从原生跳回 Unity 界面时要将Unity 取消暂停,主要代码和图如下:

1
2
3
[self dismissViewControllerAnimated:NO completion:^{
UnityPause(false);
}];

如下图所示:
030XcodeBackUnity.png

26.因为是游戏要设置全局横屏,代码和图如下:

1
2
3
4
// 设置全局横屏
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskLandscapeRight;
}

031UnityAppController.png

27.如果在Unity导出 Xcode 工程时,你的 Bundle Identifier 和在高德注册的不一致,这里需要修改 Bundle Identifier,如下图:

032XcodeMapLocation.png

28.如果报错ApiKey,需要在 UnityAppController进行设置,代码和图如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#warning 这个地方设置 apiKey
//*****************************************//
// 解决地图呈现网格问题
[[AMapServices sharedServices] setEnableHTTPS:YES];
if ([APIKey length] == 0)
{
NSString *reason = [NSString stringWithFormat:@"apiKey为空,请检查key是否正确设置。"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:reason delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
}
[AMapServices sharedServices].apiKey = (NSString *)APIKey;
//*****************************************//

033errorAppKey.png

034XcodeApiKeyError.png

035XcodeApiKeyError.png

###2017年7月13日更新:
前段时间Unity导出的il2cpp模式的工程在登录时无法加载场景,因此这段时间以来都是在mono2x模式下进行写的代码,随着最近一次更新,导出的Xcode文件报错:

Unable to insert branch island. No insertion point available. for architecture armv7

Mono2X下编译报错信息.png

网上说是由于导出的Xcode文件:Data/Managed/Assembly-CSharp.dll的文件过大导致的(上次3.4M,只比上次更新大了0.1M),说是让拆代码进行解决,暂时未处理,打算继续回归il2cpp模式,将加载场景的代码进行注释,因为我的开发是LBS部分,只需要能和Unity进行通讯即可继续开发(等待拆代码中….)

Assembly-CSharp.dll达到3.5M时Mono2X下编译报错.png

注释Unity加载场景代码.png