场景描述:
我这边制作一个SDK(含用户登录、创角、支付、登出等功能),提供给游戏研发那边接入出包ipa;为了方便研发对接SDK出ipa给我们后,我们SDK有新更新内容,避免每次更新内容都要找游戏研发替换更新SDK,我们这边制作的SDK选择动态库(至于如何替换ipa中动态库请百度)。
之前按照提供的对接文档都好好的,这次遇到了有个问题,研发开发接入调试我们这边提供的动态库SDK时候,导入了我们SDK暴漏头文件,然后调用初始化并且开启了SDK打印设置,但是真机运行调试的时候没有任何执行SDK初始化相关打印日志记录,也就是说SDK初始化逻辑都没有执行。
然后我这边协同研发进行调试,找到并解决问题,以下是分析和处理方案
1、使用File + SDK二进制文件路径
- 确认使用的SDK是动态库SDK
2、Target > Build Phases > 搜索框搜索对应framework命名 > 在Link Binary With Libraries中看动态库对应的Status
-
看到的结果是Optional
3、为啥对应的动态库是Optional呢,在add对应外部SDK文件到工程中,默认不是Required吗?
-
于是我将动态库的Optional改为Required
- 然后真机运行进行调试,但是真机运行结果报错,报错如下:
dyld[2066]: Library not loaded: @rpath/GameSDK.framework/GameSDK
Referenced from: <DA3C55C5-0011-38C1-BDE3-D9398755291A> /private/var/containers/Bundle/Application/8D726F8A-B0F2-4860-B8F3-279032424115/NewProject-mobile.app/NewProject-mobile
Reason: tried: '/private/preboot/Cryptexes/OS@rpath/GameSDK.framework/GameSDK' (errno=2), '/System/Library/Frameworks/GameSDK.framework/GameSDK' (errno=2, not in dyld cache)
Library not loaded: @rpath/GameSDK.framework/GameSDK
Referenced from: <DA3C55C5-0011-38C1-BDE3-D9398755291A> /private/var/containers/Bundle/Application/8D726F8A-B0F2-4860-B8F3-279032424115/NewProject-mobile.app/NewProject-mobile
Reason: tried: '/private/preboot/Cryptexes/OS@rpath/GameSDK.framework/GameSDK' (errno=2), '/System/Library/Frameworks/GameSDK.framework/GameSDK' (errno=2, not in dyld cache)
dyld config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/usr/lib/libBacktraceRecording.dylib:/usr/lib/libMainThreadChecker.dylib:/usr/lib/libRPAC.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib:/Developer/Library/PrivateFrameworks/GPUTools.framework/libglInterpose.dylib
4、研发之所以将动态库link配置为可选,应该是为了解决上面的报错吧;将Link Binary With Libraries中Status改为“可选”时运行没报错,但是为啥SDK初始化逻辑没执行?
- 对于动态库SDK,接入到xcode工程时候,如果Link Binary With Libraries状态设置为“可选”,那么就不会调用到动态库,Optional就忽略了那个动态库sdk(选择可选运真机运行调试时候不会加载到动态库SDK)
5、既然动态库SDK配置为“必须”,那么解决3中的真机调试报错不就能解决问题了?
-
Target > Build Settings 选择all > 输入框搜索 @rpath 看到的结果是:
-
然后我新建一个工程和查看sdk对应demo中此项配置,此项配置默认应该是:
-
然后我将@executable_path/Frameworks配置添加到游戏工程中
- 再次真机运行成功,并且调用sdk的初始化逻辑了
此步骤总结分析:游戏工程师cocos工具导出的工程,cocos导出的工程@rpath将xcode默认创建的设置进行了修改,才导致添加动态库运行报错问题
6、延伸:如果打包提供的对接SDK是静态库,外部工程接入SDK项目Link Binary With Libraries中配置可选和必须两种情况下会不会和上面动态库一样情况呢?
- 实际测试结果不一样:当SDK为静态库,Link Binary With Libraries设置可选和必须两种情况下真机运行都执行了sdk初始化逻辑,这块暂时没搞懂,暂时记录下,方便后续遇到同样问题查阅