【问题标题】:Can't compile Simulator build with Universal (fat) Framework built with Xcode 10.2+无法使用 Xcode 10.2+ 构建的通用(胖)框架编译模拟器构建
【发布时间】:2019-08-08 12:56:05
【问题描述】:

我无法为使用 Xcode 10.2+ 构建的通用(胖)框架的模拟器编译应用程序(设备编译成功)。应用程序使用来自 Objective-C 代码的框架。当从为设备构建切换到为模拟器构建时,Xcode 停止识别框架中的任何类和其他实体,因此无法编译(但在 Swift 文件中可以正确识别框架类)。

我创建通用框架的脚本类似于https://gist.github.com/sundeepgupta/3ad9c6106e2cd9f51c68cf9f475191fa(通常所有此类脚本都使用几乎相同的逻辑,并且主要在变量命名上有所不同)。

【问题讨论】:

    标签: ios swift xcode xcodebuild ios-frameworks


    【解决方案1】:

    原因

    这个问题的真正原因在于 Xcode 编译器。启动 Xcode 10.2 Apple 更改了 Framework swift 标头 (MyFramework.framework/Headers/MyFramework-Swift.h) 的生成器。现在它添加了像

    这样的行
    #elif defined(__x86_64__) && __x86_64__
    #elif defined(__i386__) && __i386__
    

    到模拟器标题和

    #elif defined(__arm64__) && __arm64__
    #elif defined(__ARM_ARCH_7A__) && __ARM_ARCH_7A__
    

    到设备头。

    因此模拟器和设备的标头变得不同。 因为通用框架的通用脚本从设备构建目录构建副本头,所以这样的框架在设备构建时工作正常,但在模拟器构建时失败。

    Apple 在Xcode 10.2 release notes 已知问题一章中发现了这个问题并提出了解决方案。

    解决方案

    解决 Apple 提到的问题的解决方案是创建组合标头,其中应包括来自设备和模拟器的原始标头:

    #include <TargetConditionals.h>
    #if TARGET_OS_SIMULATOR
    <contents of original iOS Simulator/Framework.framework/Framework-Swift.h>
    #else
    <contents of original iOS/Framework.framework/Framework-Swift.h>
    #endif
    

    关于制作胖框架的脚本,您可以通过以下方式对其进行修改:

    # Step 5. Convenience step to copy the framework to the project's directory
    cp -R "${UNIVERSAL_OUTPUT_DIR}/${PRODUCT_NAME}.framework" "${RELEASE_DIR}"
    
    # Step 6. Combine PRODUCT_NAME-Swift.h from device and simulator architectures (Xcode 10.2 issue: 48635615)
    UNIVERSAL_SWIFT_HEADER=${UNIVERSAL_OUTPUT_DIR}/${PRODUCT_NAME}.framework/Headers/${PRODUCT_NAME}-Swift.h
    
    > ${UNIVERSAL_SWIFT_HEADER}
    echo "#include <TargetConditionals.h>" >> ${UNIVERSAL_SWIFT_HEADER}
    echo "#if TARGET_OS_SIMULATOR" >> ${UNIVERSAL_SWIFT_HEADER}
    cat ${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}.framework/Headers/${PRODUCT_NAME}-Swift.h >> ${UNIVERSAL_SWIFT_HEADER}
    echo "#else" >> ${UNIVERSAL_SWIFT_HEADER}
    cat ${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PRODUCT_NAME}.framework/Headers/${PRODUCT_NAME}-Swift.h >> ${UNIVERSAL_SWIFT_HEADER}
    echo "#endif" >> ${UNIVERSAL_SWIFT_HEADER}    
    
    # Step 7. Convenience step to open the project's directory in Finder
    open "${RELEASE_DIR}"
    

    &gt; ${UNIVERSAL_SWIFT_HEADER} 需要在步骤 2 中清除复制的标头 在组合开始之前。

    【讨论】:

    • 谢谢!这救了我的皮肤。为我的 SDK 框架添加了 Objective-c 支持,但无法在 Xcode 模拟器中工作。
    • 修复有效,但是,您需要将#include &lt;TargetConditionals.h&gt; 添加到UNIVERSAL_SWIFT_HEADER 的开头,因为没有它TARGET_OS_SIMULATOR 将永远不会被定义。
    • @BoygeniusDexter 很奇怪,我从来没有遇到过这个问题?你的环境是什么?
    猜你喜欢
    • 1970-01-01
    • 2019-08-16
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 2016-03-20
    • 2011-04-28
    相关资源
    最近更新 更多