通过 Xcode 6 ,我们可以创建自己的Dynamic Cocoa Frameworks
.
因为:
-
模拟器仍然使用
32-bit
库 -
从2015年6月1日开始提交到App Store的应用更新必须包含64位支持,并使用iOS 8 SDK(developer.apple.com)构建
我们必须使胖库在设备和模拟器上运行项目 . 即支持Frameworks中的32位和64位 .
但我没有找到任何手册,如何 export 通用胖框架以便将来与其他项目集成(并与某人共享此库) .
以下是我重现的步骤:
- 在
Build Settings
中设置ONLY_ACTIVE_ARCH=NO
- 将支持
armv7 armv7s arm64 i386 x86_64
添加到Architectures
(当然)
- Build Framework并在Finder中打开它:
- 将此框架添加到另一个项目中
实际结果:
但最终我仍然遇到在设备和模拟器上同时使用此框架运行项目的问题 .
- 如果我从
Debug-iphoneos
文件夹中获取框架 - 它可以在设备上运行并在模拟器上获取错误:ld: symbol(s) not found for architecture i386
xcrun lipo -info CoreActionSheetPicker
胖文件中的体系结构:CoreActionSheetPicker是:armv7 armv7s arm64
- 如果我从
Debug-iphonesimulator
文件夹中获取框架 - 它适用于模拟器 . 我在设备上有错误:ld: symbol(s) not found for architecture arm64
xcrun lipo -info CoreActionSheetPicker
胖文件中的体系结构:CoreActionSheetPicker是:i386 x86_64
那么,如何创建一个适用于设备和模拟器的动态框架?
这个答案与Xcode 6 iOS Creating a Cocoa Touch Framework - Architectures issues有关,但并不重复 .
更新:
我找到了"dirty hack"这个案子 . 看我的answer below . 如果有人知道更方便的方式 - 请告诉我!
6 回答
@Stainlav的答案非常有用,但我做的是编译框架的两个版本(一个用于设备,一个用于模拟器),然后添加以下
Run Script Phase
以自动复制运行架构所需的预编译框架这样我就没有使用
lipo
来创建一个胖框架,而不是Realm的strip-frameworks.sh
在提交到App Store时删除不必要的切片 .基本上为此我找到了非常好的解决方案 . 你只需要遵循这些简单的步骤 .
创建一个可可触摸框架 .
将bitcode设置为否 .
选择目标并选择编辑方案 . 选择Run并从Info选项中选择Release .
无需其他设置 .
现在为任何模拟器构建框架,因为模拟器在x86架构上运行 .
单击Project Navigator中的Products组,找到.framework文件 .
右键单击它并单击在查找器中显示 . 复制并粘贴到任何文件夹中,我个人更喜欢名称'simulator' .
现在为Generic iOS Device构建框架并按照步骤6到9进行操作 . 只需将文件夹重命名为'device'而不是'simulator' .
复制设备.framework文件并粘贴到任何其他目录中 . 我更喜欢两者的直接超级目录 . 所以目录结构现在变成:
桌面
设备
MyFramework.framework
模拟器
MyFramework.framework
MyFramework.framework现在打开终端并cd到桌面 . 现在开始输入以下命令:
就是这样 . 在这里,我们合并MyFramework.framework中存在的MyFramework二进制文件的模拟器和设备版本 . 我们获得了一个通用框架,可以为包括模拟器和设备在内的所有架构构建 .
我的答案涵盖以下几点:
制作适用于模拟器和设备的框架
如何导出“胖”Cocoa Touch Framework(适用于模拟器和设备)?
体系结构x86_64的未定义符号
ld:找不到架构x86_64的符号
步骤1:首先使用Simulator目标构建框架
步骤2:模拟器构建过程成功后,现在为您的框架构建设备目标选择或通用iOS设备选择
第3步:现在选择你的框架目标,并在“Build Phases”下选择“Add Run Script”并复制下面的脚本代码)
Step4:最后,再次构建,您的框架已经为模拟器和设备兼容性做好了准备 . 欢呼!!!!
[注意:我们必须在最终步骤4之前准备好兼容的框架(模拟器和设备架构兼容,如果不是,请正确执行上述步骤1和2)
参见参考图片:
将以下代码放入shell区域:
这不是那么明确的解决方案,但只有办法,我发现:
在
Build Settings
中设置ONLY_ACTIVE_ARCH=NO
为模拟器构建库
为设备构建库
在您的框架的控制台
Products
文件夹中打开(您可以打开它从那里打开框架文件夹和cd ..
)Products
文件夹运行 this 脚本 . 它在此文件夹中创建fat Framework . (或按照以下 3. 4. 中的说明手动完成)要么:
YourFrameworkName
替换为您的框架名称)./YourFrameworkName.framework
- is ready-to-use fat binary! 您可以将其导入您的项目!For project, that not in Workspaces:
您也可以尝试使用this gist,如here所述 . 但似乎它不适用于工作空间中的项目 .
我只是想通过@odm更新this great answer . 从Xcode 10开始,
CURRENT_ARCH
变量不再反映构建体系结构 . 所以我改变了脚本来检查平台:我还在复制之前添加了一行来清除目标目录,因为我注意到子目录中的其他文件不会被覆盖 .
这个答案的实际情况是:2015年7月 . 事情很可能会发生变化 .
TLDR;
目前Xcode没有自动导出通用胖框架的工具,因此开发人员必须求助于手动使用
lipo
工具 . 同样根据this radar提交给AppStore开发人员之前,框架的消费者也必须使用lipo
从框架中剥离模拟器切片 .接下来是更长的答案
我在这个主题上做了类似的研究(答案底部的链接) .
我没有找到任何关于分发的官方文档,所以我的研究是基于对Apple Developer Forums,Carthage和Realm项目的探索以及我自己用
xcodebuild
,lipo
,codesign
工具的实验 .这是Apple Developer Forums主题Exporting app with embedded framework的长引用(带有一点标记):
这描述的过程与@skywinder在回答中的做法非常相似 .
这是Carthage uses lipo和Realm uses lipo .
IMPORTANT DETAIL
有雷达:Xcode 6.1.1 & 6.2: iOS frameworks containing simulator slices can't be submitted to the App Store并在Realm#1163和Carthage#188上进行了长时间的讨论,结束于特殊的解决方法:
before submission to AppStore iOS framework binaries must be stripped off back from simulator slices
迦太基有特殊代码:CopyFrameworks和相应的文件:
Realm有特殊脚本:strip-frameworks.sh和相应的文档:
还有好文章:Stripping Unwanted Architectures From Dynamic Libraries In Xcode .
我自己使用了Realm的
strip-frameworks.sh
,它完美地为我工作而没有任何修改,当然任何人都可以自由地从头开始写一个 .我建议阅读的主题链接,因为它包含此问题的另一个方面:代码签名 - Creating iOS/OSX Frameworks: is it necessary to codesign them before distributing to other developers?