iOS导出unityFramework历程

一、背景

由于定义了unity和原生之间交互的桥,因此在导出unity项目后,需要将桥源码加到unityFramework里面参与编译,编译出动态库。

二、问题及排查历程

符号未定义

在unity那个demo里面进行桥使用:

发现符号未定义的问题:

然后发现为什么库里面其他的符号可以被使用:

符号未定义原因

细看不同之处:

原来加了这个显示,符号默认对外界隐藏。查看动态库设置参数,果然如此:

于是乎我也在自定义的类加上这个参数不就解决了?(哈哈哈,只能说运气没有站在我这边,啪啪打脸):

在自定义的类声明前面,也加上了这个标识,再次编译,wtf还是报符号未定义的错误。然后开始反思为什么会出现这样的效果,明明是一样的。我甚至尝试把这个类定义到UnityFramework文件里面,以避免库单独对这个文件做了什么处理。结果还是不行(依然报错)。然后再次问:明明是一样的,为什么还会报这个问题????但是真的是一样的吗?(使用的时候还是有不一样的)请看:

会发现,没有报错的12行是通过bundle.principalclass去获取的class,查看静态库的info.plist可以发现,这个主要类设置的就是UnityFramework

那么至于为什么会出现符号未定义的问题也就显而易见了:因为这个动态库是懒加载的,并不是我们常用的系统自动加载的动态库。报符号未定义的错是因为在编译时,如果调用了[HostRouterApi sharedInstance].sendEventToHostBlock,编译器会去验证app的mach-o文件以及它依赖的动态库的mach-o文件中是否有这个类的定义。

由于在编译时,程序还没有加载动态库UnityFramework,而程序只包含了HostRouterApi类的头文件,并没有它对应的.m文件(编译器只会将.m文件编译到最终的mach-o文件中),所以编译器在app的mach-o文件以及它依赖的动态库中找不到HostRouterApi类的定义,然后编译器就报错了。所以如果我们把12行换成13行,也会出现同样的报错:

三、究竟设置了啥,让这个demo只能懒加载动态库

一开始以为是因为Link Binary With Libraries(构建阶段(Build Phase),用于指定要与你的应用程序一起链接的二进制文件。而且因为正常我们引入framework的时候,这里也会存在。但是Unity-iPhone这个demo是没有的)。

但是经过自己创建新的demo,去验证发现,动态库依然会主动被加载,并不需要手动去加载(没有模拟出Unity-iPhone这个demo的效果)。

这个问题还有待确定(为什么unity导出来的demo会出现使用类编译找不到符号的错误)。。。

四、修复措施

新建的类按照这个方法,让其符号是可见的,然后直接导入该动态库使用即可。

五、自定义组件

修改组件名称

不要直接修改target名称

直接修改target名称虽然可以达到修改组件名称的目的,但是后续unity项目无法继续导出项目(会因为路径问题导致导出出错)。

修改framework对应target的build settings里面的product name

更新bridge文件

bridge文件直接放在unityframework参与编译

bridge文件直接拖进unityframework里面参与编译,有更新的时候直接替换bridge文件即可。

unityframework依赖bridge组件

bridge作为一个单独的组件,unityframework依赖该组件:

注意要把use_frameworks!注释掉,否则unityframework里面不会有bridge组件里面的符号(也就达不到最终只提供一个framework给业务的目的)。

而且LZAvatarBridge需要支持bitcode(因为unityframework支持)

但是由于最新苹果要求关掉该配置,因此需要把unityframework默认的yes改成NO。LZAvatarBridge也不用开启bitcode。

自动获取main函数的两个参数

objectivec 复制代码
- (void)runEmbeddedWithArgc:(int)argc argv:(char*[])argv appLaunchOpts:(NSDictionary*)appLaunchOpts

启动unity引擎需要main入口函数的两个参数(int)argc 和 argv:(char*[])argv,一开始尝试让组件使用方在main函数里面将这两个参数传给组件。但是细想一下,发现这样不太美观(主要是即构也没这样搞,那么肯定是内部有办法去获取这两个参数的)。经过一顿牛逼的操作后,终于实现:

ini 复制代码
        NSArray<NSString *> *arguments = [[NSProcessInfo processInfo] arguments];
        // 创建一个 char ** 数组,长度为 arguments 数组的长度加一(用于存储 NULL 结束符)
        char **argv = (char **)malloc((arguments.count + 1) * sizeof(char *));
        // 遍历 arguments 数组,将每个 NSString 对象转换为对应的 C 字符串
        for (NSInteger i = 0; i < arguments.count; i++) {
            NSString *argument = arguments[i];
            const char *cString = [argument UTF8String];
            // 复制 C 字符串到动态分配的内存中
            argv[i] = strdup(cString);
        }
        // 最后一个元素设置为 NULL,表示参数列表的结束
        argv[arguments.count] = NULL;
        int argc = (int)arguments.count;
相关推荐
大熊猫侯佩2 小时前
黑衣人档案:用 Apple Foundation Models + SwiftUI 打造 AI 聊天机器人全攻略
ios·swiftui·ai编程
大熊猫侯佩2 小时前
侠客行・iOS 26 Liquid Glass TabBar 破阵记
ios·swiftui·swift
2501_916007474 小时前
手机使用过的痕迹能查到吗?完整查询指南与步骤
android·ios·智能手机·小程序·uni-app·iphone·webview
從南走到北5 小时前
JAVA国际版同城外卖跑腿团购到店跑腿多合一APP系统源码支持Android+IOS+H5
android·java·ios·微信小程序·小程序
alengan8 小时前
苹果企业签名流程
ios·iphone
Digitally16 小时前
如何在Mac上同步iPhone短信
macos·ios·iphone
2501_9151063219 小时前
App HTTPS 抓包 工程化排查与工具组合实战
网络协议·ios·小程序·https·uni-app·php·iphone
2501_9160088921 小时前
金融类 App 加密加固方法,多工具组合的工程化实践(金融级别/IPA 加固/无源码落地/Ipa Guard + 流水线)
android·ios·金融·小程序·uni-app·iphone·webview
2501_915921431 天前
Fastlane 结合 开心上架(Appuploader)命令行版本实现跨平台上传发布 iOS App 免 Mac 自动化上架实战全解析
android·macos·ios·小程序·uni-app·自动化·iphone
游戏开发爱好者81 天前
iOS 上架要求全解析,App Store 审核标准、开发者准备事项与开心上架(Appuploader)跨平台免 Mac 实战指南
android·macos·ios·小程序·uni-app·iphone·webview