【问题标题】:iOS Framework Tests fail in Xcode WorkspaceXcode Workspace 中的 iOS 框架测试失败
【发布时间】:2016-04-07 06:12:30
【问题描述】:

我有一个 Xcode 工作区,其中包含 2 个 Swift 项目、OAuth 和 Commons。
每个项目都有一个 iOS 框架目标和一个测试目标。它们不相互依赖。
Commons 项目无依赖关系,而 OAuth 框架目标导入 WebKit (import WebKit)。

现在,如果我在 Xcode 中运行测试,OAuth 测试工作正常,但 Commons 测试失败并显示以下 Xcode 错误日志:

Test target CommonsTests encountered an error (Early unexpected exit, operation never finished bootstrapping - no restart will be attempted)

如果我使用以下命令从命令行运行测试

xcodebuild -workspace Workspace.xcworkspace -configuration Debug -destination "platform=iOS Simulator,name=iPhone 6" -scheme OAuth test

xcodebuild -workspace Workspace.xcworkspace -configuration Debug -destination "platform=iOS Simulator,name=iPhone 6" -scheme Commons test

第二个命令后出现以下错误:

The bundle “CommonsTests” couldn’t be loaded because it is damaged or missing necessary resources. Try reinstalling the bundle.
(dlopen_preflight(~/Library/Developer/Xcode/DerivedData/Workspace-aslcnsaomwggxqcxoozzfuztgszf/Build/Products/Debug-iphonesimulator/CommonsTests.xctest/CommonsTests): Library not loaded: @rpath/libswiftWebKit.dylib
Referenced from: ~/Library/Developer/Xcode/DerivedData/Workspace-aslcnsaomwggxqcxoozzfuztgszf/Build/Products/Debug-iphonesimulator/OAuth.framework/OAuth Reason: image not found)

我的设置可能有什么问题? 其他人也会出现这个问题吗?


解决方法:

1) 如果我还在 CommonsTests 捆绑包中包含 WebKit,一切正常。 但由于 OAuth 和 Commons 框架之间没有依赖关系,我看不出有任何必要这样做的理由。

2) 如果我将 OAuth 项目(和目标)重命名为 OAuth2 之类的,一切正常。 这真的很奇怪。可能是名称冲突或缓存问题。

重命名解决方法是否可以解决其他人的问题?


示例项目:https://www.dropbox.com/s/dn3ywhxlc9kb6y4/SampleProject.zip?dl=0

设置:
Xcode 7.3(Xcode 7.2 也出现错误)
OS X 10.11.4(OS X 10.11.3 也出现错误)

【问题讨论】:

    标签: ios xcode xctest


    【解决方案1】:

    再次查看问题后,我可以找到奇怪行为的原因。

    简答:
    /System/Library/PrivateFrameworks/OAuth.framework/OAuth 有一个私有 OAuth Apple 框架,这会导致与我自己的 OAuth 框架发生名称冲突,因为 xctest 似乎链接了这个框架。

    长答案:
    xctestXCTest.framework 似乎从 Private Frameworks 文件夹加载 OAuth.framework。

    如果在 Xcode 中使用工作空间,则测试环境为 dyld 使用以下环境变量:

    "DYLD_FRAMEWORK_PATH“ = "/Users/{USER}/Library/Developer/Xcode/DerivedData/{PROJECT}/Build/Products/Debug-iphonesimulator:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks“;

    变量有以下作用:

    DYLD_FRAMEWORK_PATH
                  This is a colon separated list of directories that contain  frameworks.   The  dynamic  linker
                  searches  these  directories  before  it  searches  for the framework by its install name.  It
                  allows you to test new versions of existing frameworks. (A framework is a library install name
                  that  ends  in the form XXX.framework/Versions/YYY/XXX or XXX.framework/XXX, where XXX and YYY
                  are any name.)
    
                  For each framework that a program uses, the dynamic linker looks for  the  framework  in  each
                  directory  in  DYLD_FRAMEWORK_PATH  in turn. If it looks in all the directories and can't find
                  the framework, it searches the directories in DYLD_LIBRARY_PATH in turn.  If  it  still  can't
                  find   the   framework,   it   then   searches   DYLD_FALLBACK_FRAMEWORK_PATH  and  DYLD_FALL-BACK_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH
                  BACK_LIBRARY_PATH in turn.
    

    DYLD_FRAMEWORK_PATH 定义框架的搜索目录并覆盖默认搜索路径和安装名称,它们嵌入到依赖的二进制文件中。即使二进制文件指定了框架安装路径,例如 ​/System/Library/Frameworks/OAuth 环境变量导致目录的行为 /Users/{USER}/Library/Developer/Xcode/DerivedData/{PROJECT}/Build/Products/Debug-iphonesimulator 无论实际安装名称如何,都会搜索 ​OAuth.framework/OAuth 二进制文件。

    这种行为是有意的,因为它允许使用较新版本覆盖现有二进制文件中的框架,而无需重新编译二进制文件。

    但是,如果两个框架必须具有相同的名称,它也可能导致二进制文件的误导性链接。然后,可以加载具有相同名称的框架之一,即使另一个是由路径指定的。如果第一个目录包含在DYLD_FRAMEWORK_PATH 中,或者在另一个目录之前或根本不包含,则选择第一个是因为它的名称,而不考虑指定的安装名称路径。

    具体例子:

    xctest 二进制加载命令: ​/System/Library/PrivateFrameworks/OAuth.framework/OAuth (compatibility version 300.0.0, current version 1280.24.0)

    OAuth 存在于以下路径中:
    /System/Library/PrivateFrameworks/OAuth.framework/OAuth /Users/{USER}/Library/Developer/Xcode/DerivedData/{PROJECT}/Build/Products/Debug-iphonesimulator/OAuth.framework/OAuth

    xctest 使用以下环境变量启动:
    "DYLD_FRAMEWORK_PATH“ = "/Users/{USER}/Library/Developer/Xcode/DerivedData/{PROJECT}/Build/Products/Debug-iphonesimulator:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks“;

    然后是 OAuth 框架
    /Users/{USER}/Library/Developer/Xcode/DerivedData/{PROJECT}/Build/Products/Debug-iphonesimulator/OAuth.framework/OAuth
    即使安装名称为
    /System/Library/PrivateFrameworks/OAuth.framework/OAuth

    ,也会使用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-31
      • 2014-05-26
      • 2018-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-13
      相关资源
      最近更新 更多