此崩溃是一个阻塞问题,我使用以下步骤重现该问题:
创建一个 Cocoa Touch 框架项目
添加一个swift文件和一个类Dog
为设备构建框架
在 Swift 中创建单视图应用程序
将框架导入应用项目
在 ViewController 中从框架中实例化 swift 类
在设备上构建并运行应用程序
该应用程序在启动时立即崩溃,这是控制台日志:
dyld: Library not loaded: @rpath/FrameworkTest03.framework/FrameworkTest03
Referenced from: /var/mobile/Applications/FA6BAAC8-1AAD-49B4-8326-F30F66458CB6/FrameworkTest03App.app/FrameworkTest03App
Reason: image not found
我尝试在 iOS 7.1 和 8.0 设备上构建,它们都有相同的崩溃。但是,我可以构建一个应用程序并在模拟器上运行良好。另外,我知道我可以将框架更改为在 Link Binary With Libraries 中将必需的形式更改为可选,但它并没有完全解决问题,当我创建 Dog 的实例时应用程序崩溃了。设备和模拟器上的行为不同,我怀疑我们无法使用 Xcode 的 beta 版本为设备分发框架。任何人都可以阐明这一点吗?
Link Binary with Libraries
中,并且 Xcode 知道将它们复制到您的应用程序包中,而对于自定义框架,这根本不发生。
对于大于或等于 8 的 iOS
在目标的 General 选项卡下,在 Embedded Binaries 部分中添加框架。这会将框架复制到已编译的框架中,以便可以在运行时链接到它。
https://i.stack.imgur.com/zRwSS.png
为什么会这样? :因为您要链接的框架被编译为动态链接的框架,因此在运行时链接到。
** 注意:** 嵌入自定义框架仅在 iOS > 8 中受支持,因此适用于旧版本 iOS 的替代解决方案如下。
对于小于 8 的 iOS
如果您影响此框架(有权访问源代码/构建过程),您可以将此框架更改为静态链接而不是动态链接。这将导致代码包含在您编译的应用程序中,而不是在运行时链接到,因此不必嵌入框架。
** 方法:** 在框架的 Build Setting 选项卡下,在 Linking 部分,将 Mach-O Type 更改为 Static Library。您现在不需要将框架包含在嵌入式二进制文件下。
https://i.stack.imgur.com/6yKzU.png
包括资产:要包括图像、音频或 xib/nib 文件等内容,我建议创建一个包(本质上是一个目录,更多信息在这里 bit.ly/ios_bundle),然后使用 NSBundle 从包中加载资产。
Swift is not supported for static libraries
仅仅将框架拖到您的项目中是不够的。这就像在同一个球场但找不到你的孩子。按着这些次序:
1)创建你的框架
开发你的框架。
开发完成后,COMMAND+B 构建您的框架并确保您收到“构建成功”。
https://i.stack.imgur.com/jdTPo.png
2)访问您的框架
一旦您的框架项目成功构建,您就可以在项目的 Products 文件夹中访问它。
https://i.stack.imgur.com/vmBPE.png
右键单击您的 .framework 并选择“在 Finder 中显示”。
https://i.stack.imgur.com/TaAwN.png
3)在你的项目中放置框架
将 .framework 从 Finder 窗口拖放到应用项目的“Framework”文件夹中。
https://i.stack.imgur.com/yF10y.png
4) 为框架配置应用程序项目
选择项目中的顶层
https://i.stack.imgur.com/8g9nA.png
选择你的目标
https://i.stack.imgur.com/AlCw7.png
转到“Build Phases”,然后“Link Binary with Libraries”,并确保您的框架包含在可选选项中。
https://i.stack.imgur.com/qTQ9M.png
仍在“构建阶段”中,转到左上角并选择 + 按钮。在下拉列表中选择“新建复制文件阶段”。
https://i.stack.imgur.com/rUzCO.png
向下滚动到新的“复制文件”部分并确保将目标设置为“框架”。将子路径留空。然后点击左下角的+按钮。
https://i.stack.imgur.com/sz6Cc.png
您将看到您的项目层次结构。向下滚动到您在第 3 步中添加框架的“框架”文件夹,或在顶部的搜索栏中搜索它。选择您的框架并单击“添加”。
https://i.stack.imgur.com/nbtJ7.png
确保您的框架包含在选中的“代码登录副本”中。
https://i.stack.imgur.com/nrFNd.png
5)清理,然后运行你的项目
命令+SHIFT+K
命令+R
首先尝试在 Command+Option+Shift+K 之后构建。如果仍然失败,请执行以下步骤。
如果有人在 Xcode 8 中遇到此错误,请在目标的“常规”选项卡下将您的框架状态更改为“可选”而不是“必需”。
https://i.stack.imgur.com/VGhy1.png
我使用 Swift3/Xcode 8.1 创建了一个框架,并在一个 Objective-C/Xcode 8.1 项目中使用它。要解决此问题,我必须启用 Build Options
下的 Always Embed Swift Standard Libraries
选项。
看看这个截图:
https://i.stack.imgur.com/sIlyu.png
Embedded Binaries
部分中。那么为什么这使它起作用呢?
我在 iOS 9.x 版本中遇到了同样的问题
ISSUE IS: App crashes as soon as I open the app with below error.
dyld: Library not loaded: /System/Library/Frameworks/UserNotifications.framework/UserNotifications Referenced from: /var/containers/Bundle/Application/######/TestApp.app/TestApp Reason: image not found
我已通过在 UserNotifications.framework
框架的 Linked Frameworks and Libraries
中将 Required
更改为 Optional
解决了这个问题。
我必须(在此处提到的内容之上)将以下行添加到 Build Settings 选项卡下的 Runpath Search Paths:
@executable_path/Frameworks
https://i.stack.imgur.com/yihsd.png
您需要将框架添加到新的复制文件构建阶段,以确保在运行时将框架复制到应用程序包中。
有关详细信息,请参阅 How to add a 'Copy Files build phase' to my Target。
如果您使用的是 Xcode 11 或更新版本:
导航到目标的设置并选择常规。
https://i.stack.imgur.com/yOEX8.png
向下滚动到框架、库和嵌入式内容。如有必要,请确保为嵌入选项选择了嵌入并签名或嵌入不签名值。
https://i.stack.imgur.com/kx5Xu.png
这是由 Dynamic Linker
引起的运行时错误
dyld: Library not loaded: @rpath/<some_path>
Referenced from: <some_path>
Reason: image not found
带有 @rpath
的错误 Library not loaded
表明 Dynamic Linker
找不到二进制文件。
检查是否将动态框架添加到前面的目标 General -> Frameworks, Libraries, and Embedded Content (Embedded Binaries)。如果需要[关于],可以将框架拖放到项目中复制项目非常简单,并且错过了将框架添加为框架、库和嵌入式内容中的隐式依赖项(或签入添加到目标)。在这种情况下,在编译时 Xcode 将其构建为成功,但是当您运行它时,您会收到运行时错误 检查使用者(应用程序)和生产者(动态框架)之间的 @rpath 设置:
动态框架:构建设置 -> 动态库安装名称
构建设置 -> 动态库安装名称
应用程序:构建设置 -> 运行路径搜索路径构建阶段 -> 嵌入框架 -> 目标、子路径
构建设置 -> 运行路径搜索路径
构建阶段 -> 嵌入框架 -> 目标,子路径
框架的 Mach-O 文件[关于] - 动态库和应用程序的框架、库和嵌入内容[关于] - 不嵌入。
动态链接器
Dynamic Library Install Name(LD_DYLIB_INSTALL_NAME)
由 loadable bundle
(Dynamic framework
作为派生词)使用,其中 dyld
发挥作用
Dynamic Library Install Name
- 二进制文件的路径(不是 .framework)。是的,它们具有相同的名称,但 MyFramework.framework
是一个 packaged bundle
,其中包含 MyFramework
二进制文件和资源。
此目录路径可以是绝对路径或相对路径(例如 @executable_path
、@loader_path
、{ 11})。相对路径更可取,因为它与锚点一起更改,当您将捆绑包作为单个目录分发时很有用
绝对路径 - Framework1 示例
//Framework1 Dynamic Library Install Name
/some_path/Framework1.framework/subfolder1
Relative path
允许您以动态方式定义路径。
@executable_path
@executable_path - 相对于加载框架的 executable 二进制文件
用例:Application
内的 Dynamic framework
(应用程序二进制文件路径为 @executable_path)或更复杂的示例 App Extension
[About]是 Containing App
的一部分,其中包含 Dynamic Framework
。 Application
目标(应用程序二进制路径是 @executable_path)和 App Extension
目标(应用程序扩展二进制路径是 @executable_path)有 2 个 @executable_path
- Framework2 示例
//Application bundle(`.app` package) absolute path
/some_path/Application.аpp
//Application binary absolute path
/some_path/Application.аpp/subfolder1
//Framework2 binary absolute path
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1
//Framework2 @executable_path == Application binary absolute path <-
/some_path/Application.аpp/subfolder1
//Framework2 Dynamic Library Install Name
@executable_path/../Frameworks/Framework2.framework/subfolder1
//Framework2 binary resolved absolute path by dyld
/some_path/Application.аpp/subfolder1/../Frameworks/Framework2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1
@loader_path
@loader_path - 相对于导致框架被加载的包。如果它是一个应用程序,它将与 @executable_path
用例相同:带有嵌入式框架的框架 - Framework3_1 和 Framework3_2 内部
//Framework3_1 binary absolute path
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1
//Framework3_2 binary absolute path
/some_path/Application.аpp/Frameworks/Framework3_1.framework/Frameworks/Framework3_2.framework/subfolder1
//Framework3_1 @executable_path == Application binary absolute path <-
/some_path/Application.аpp/subfolder1
//Framework3_1 @loader_path == Framework3_1 @executable_path <-
/some_path/Application.аpp/subfolder1
//Framework3_2 @executable_path == Application binary absolute path <-
/some_path/Application.аpp/subfolder1
//Framework3_2 @loader_path == Framework3_1 binary absolute path <-
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1
//Framework3_2 Dynamic Library Install Name
@loader_path/../Frameworks/Framework3_2.framework/subfolder1
//Framework3_2 binary resolved absolute path by dyld
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1/../Frameworks/Framework3_2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework3_1.framework/Frameworks/Framework3_2.framework/subfolder1
@rpath - 运行路径搜索路径
框架2示例
以前我们必须设置一个框架来使用 dyld。这不方便,因为相同的框架不能用于不同的配置。由于此设置是在框架目标端进行的,因此无法为不同的消费者(应用程序)配置相同的框架
@rpath
是一个复合概念,它依赖于外部(应用程序)和嵌套(动态框架)部分:
应用程序:运行路径搜索路径(LD_RUNPATH_SEARCH_PATHS) - @rpath - 定义将被 @rpath 替换的模板列表。消费者使用@rpath 词指向此列表@executable_path/../Frameworks Review Build Phases -> Embed Frameworks -> Destination, Subpath 以确定嵌入框架的确切位置
运行路径搜索路径 (LD_RUNPATH_SEARCH_PATHS) - @rpath - 定义了将被 @rpath 替换的模板列表。消费者使用@rpath 词指向此列表@executable_path/../Frameworks
查看 Build Phases -> Embed Frameworks -> Destination, Subpath 以确定嵌入框架的确切位置
动态框架:动态库安装名称(LD_DYLIB_INSTALL_NAME) - 指出@rpath 与二进制文件@rpath/Framework2.framework/subfolder1 的本地包路径一起使用
动态库安装名称 (LD_DYLIB_INSTALL_NAME) - 指出 @rpath 与二进制 @rpath/Framework2.framework/subfolder1 的本地包路径一起使用
//Application Runpath Search Paths
@executable_path/../Frameworks
//Framework2 Dynamic Library Install Name
@rpath/Framework2.framework/subfolder1
//Framework2 binary resolved absolute path by dyld
//Framework2 @rpath is replaced by each element of Application Runpath Search Paths
@executable_path/../Frameworks/Framework2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1
*../
- 转到当前目录的父目录
otool
- 目标文件显示工具
//-L print shared libraries used
//Application otool -L
@rpath/Framework2.framework/subfolder1/Framework2
//Framework2 otool -L
@rpath/Framework2.framework/subfolder1/Framework2
//-l print the load commands
//Application otool -l
LC_LOAD_DYLIB
@rpath/Framework2.framework/subfolder1/Framework2
LC_RPATH
@executable_path/../Frameworks
//Framework2 otool -l
LC_ID_DYLIB
@rpath/Framework2.framework/subfolder1/Framework2
install_name_tool
使用 -rpath
更改动态共享库安装名称
CocoaPods
使用 use_frameworks!
[About] 来规范 Dynamic Linker
https://i.stack.imgur.com/feogf.png
然后清理并构建。
令人惊讶的是,并非所有必要的部分都在这里记录,至少对于 Xcode 8 而言。
我的案例是作为同一工作区一部分的定制框架。事实证明,它的构建不正确。基于 jeremyhu 对此线程的最后回复:
https://forums.developer.apple.com/thread/4687
我必须在 Framework 项目的 Build Settings
下设置 Dynamic Library Install Name Base
(DYLIB_INSTALL_NAME_BASE
),然后重新构建它。它被错误地设置为 $(LOCAL_LIBRARY_DIR)
,我不得不将其更改为 @rpath
。
因此,在 App 项目的链接处理阶段,它指示宿主 App 在运行时从 /Library/Frameworks/fw.Framework/fw
(如运行时文件系统的根目录)而不是 应用路径/Frameworks/fw.Framework/fw
关于所有其他设置:它确实必须在 Build Phases
中的 3 个位置,但是当您将其添加到 General
标签的 Embedded Binaries
设置时,这些都是一次性设置的托管应用程序。
我确实没有必须设置一个额外的 Copy Files
阶段,无论如何,这对于嵌入阶段来说似乎是多余的。通过检查构建记录的尾部,我们可以确保这不是必需的。
PBXCp /Users/xyz/Library/Developer/Xcode/DerivedData/MyApp-cbcnqafhywqkjufwsvbzckecmjjs/Build/Products/Debug-iphoneos/MyFramework.framework
[删除了许多冗长的行,但从 Xcode UI 中的简化脚本中可以清楚地看到。]
我仍然不知道为什么 Xcode 错误地设置了我的 DYLIB_INSTALL_NAME_BASE
值。
最近在较旧的 iphone(例如 iPhone 6)和 Xcode(11.3.1)上导入 CoreNFC 时遇到了这个问题。我能够让它工作
在您的项目中,选择目标。转到顶部的常规选项卡。在“框架、库和嵌入式内容”部分下,添加框架(对我来说是 CoreNFC)。重复其他目标。单击顶部的 Build Phases 并展开“Link Binary with Libraries”。使麻烦的框架成为可选的(从必需的)。
这使我无需进行任何代码更改即可为较旧/较新的 iPhone 进行编译。我希望这对其他人有帮助。
我的环境:Cocos2d 2.0、Box2d、Objective C
除了上面的其他答案之外,我最后去了 General 选项卡并使 WatchKit 成为 Optional。
https://i.stack.imgur.com/mUI4A.png
在我的情况下,解决方案是从 Embedded Binaries 中删除已编译的框架,这是工作区中的一个独立项目,清理并重建它,最后重新添加到 Embedded Binaries。
如果您使用第三方框架,并使用 Cocoapods 作为依赖项管理器,请尝试执行 pod install
来刷新您的 pod。
这次崩溃发生在我正在使用的第三方库上,很高兴上述解决方案对我有用,希望它对你有用!
https://i.stack.imgur.com/cL5OH.png
通过在 Build Phases->Embed Frameworks 上取消选择“仅在安装时复制”为我解决了
我遇到过同样的问题。我尝试使用以前从未使用过的 iPhone 构建我的项目,并且没有添加新框架。对我来说,清理工作正常(Shift+Command+K)。也许是因为我使用 Xcode 7 的 beta 5 和带有 iOS 9 Beta 的 iPhone 6,但它确实有效。
对于 Xcode 中使用 pod 的任何项目或框架项目,避免动态库 (dylb) 无法加载的一种简单方法是将 pod 文件设置为静态模式下的 ink。为此,请确保不要在您的 pod 文件中写入以下行。
use_frameworks!
从您保存的文件中删除该行后,只需从控制台运行:
$ pod update
就我而言,我的项目是由 Objective-c 编写的,并且在库中有 Swift 文件。因此,我将项目的“构建设置”选项卡中的“始终嵌入 Swift 标准库”更改为“是”,它变得完全没问题。
简单的解决方案是按照此屏幕截图进行操作,然后崩溃就会消失:
https://i.stack.imgur.com/VAPc4.png
注意:这是 Xcode 11.5
如果有开发 pod 从模拟器安装中删除您的应用程序从 pod -> clean -> 再次运行...
当我创建一个新的配置和构建方案时也是如此。
所以我的解决方案是运行
pod install
对于这个新创建的配置。
对我来说,我不得不将 XcodeKit.framework 从“Do Not Embed”->“Embed & Sign”切换
https://i.stack.imgur.com/E7Mid.png
https://i.stack.imgur.com/sa8o9.png
尝试将 Build Settings 中的标志 ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES
(在早期的 xcode 版本中:Embedded Content Contains Swift Code
)从 NO 更改为 YES。
Xcode 11
导航到目标的设置并选择常规。寻找“框架、库和嵌入式内容”保持“不嵌入”并确保您的所有目标(如果您有多个)只设置了它自己的框架而不是其他目标。
在 Xcode 11 中
我面临同样的问题
在常规选项卡>“框架、库和嵌入内容”中更改“不嵌入”仍然会导致相同的错误。
为我解决的问题是在 Build Phases Tab > Embed Frameworks 部分添加框架
- 更新 - -
我观察到在以前版本的 Xcode Embed Frameworks Section 构建的项目中,在 Xcode 11 中运行时不可用,找到以下步骤来实现解决方案:
1:首先需要在 Build Phases 选项卡下添加 New Copy Files Phase。
https://i.stack.imgur.com/2bRVj.png
https://i.stack.imgur.com/y0cls.png
3:将目标更改为框架。
https://i.stack.imgur.com/IXVmM.png
4:添加发生错误的框架。
https://i.stack.imgur.com/7SiVe.png
对于 SumUp 用户,如果您正在加载最新的 SumUpSDK.xcFramework,则需要确保从应用程序的 Target 的 General 选项卡中将其设置为“Embed & Sign”。
即颠倒上述说法(使其更容易理解):
转到“项目导航器”(即显示所有项目项目等的第一个图标)从树的顶部选择您的项目。在页面中间的菜单上(略向右),在“Targets”下选择您的应用程序 从顶部选项卡中,选择“General” 向下滚动到“Frameworks, Libraries and Embedded Content” 从列表中选择您的 Lib从旁边的下拉列表中选择“嵌入并签名”。清洁重新构建并运行。
我希望这有帮助。
H
转到 xcode 中的文件 -> 工作区设置单击旁边出现的箭头 /Users/apple/Library/Developer/Xcode/DerivedData 选择派生数据并将其移至垃圾箱。相当xcode并重新打开它。清理项目并再次运行。
以上步骤解决了我的问题。
Embed & Sign