伞框架

时间:2016-12-30 14:19:13

标签: ios swift frameworks

我创建了一个框架,其中插入了第二个框架,即所谓的“伞形框架”。当我在测试应用程序中插入框架(嵌入式二进制文件和链接框架和库,两者)无法构建应用程序时,我收到以下错误:

ld: framework not found 'embeddedInMyFramework' for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

比在嵌入式二进制文件和链接的框架和库中添加该框架(embeddedInMyFramework)并尝试构建比工作正常。稍后从嵌入式二进制文件和链接的框架和库中删除该框架,仍然可以正常工作。有人可以帮我解决这个问题,不确定当我第一次向嵌入式二进制文件添加框架时会发生什么,以及如何解决这个问题(如果不加入嵌入式二进制文件,它可以以某种方式工作)

3 个答案:

答案 0 :(得分:15)

我能够建立一个有效的伞形框架并写下我的方法。

步骤5应删除链接器错误ld: framework not found ..


设定:

  • 基于Swift的“客户”项目,其中以伞形框架为依赖

  • 动态框架(主要是C ++和ObjC),它是Umbrella Framework的依赖


步骤:

  1. 将Umbrella Framework与其依赖(子)框架链接起来,并确保在构建时将其复制到产品中。
  2. Setting of Project -> Build Phases


    2.将依赖(子)框架的位置添加到Umbrella Framework项目的Framework Search Paths

    Setting of Project -> Build Settings


    3.在“客户端”项目中,确保链接并嵌入伞形框架

    General Setting Client


    4.确保将Umbrella Framework复制(client-)应用程序包中,以避免dyld: Library not loaded: @rpath/...错误。 通常在...Build/Products/Debug-iphoneos/YOUR_CLIENT_APP.app下的(client-)应用程序现在应该在名为Frameworks的文件夹中包含您的Umbrella Framework。

    Project Setting Embed Framework


     5.在“客户端”项目中确保将“伞形框架”的路径添加到Framework Search Paths  如果ld: framework not found '[Framework_Name]' for architecture ...错误仍然存​​在,您还可以在此处添加(子)框架的路径。

    Project setting framework search path

答案 1 :(得分:3)

这是一个演示项目:

Umbrella Framework Demo

这一行下的所有答案都是错误的,因为他们只是手动将子框架复制到"伞框架中#34;

Embedding a framework within a framework (iOS 8+)

How to create an umbrella framework in iOS SDK?

How to add a framework inside another framework (Umbrella Framework)

Umbrella framework

首先我们应该知道"伞框架" Mac OS中的概念不是在iOS中,官方文档在这里

https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/CreationGuidelines.html#//apple_ref/doc/uid/20002254-BAJHGGGA

如果您想创建一个不推荐的" UmbrellaFramework",您必须一步一步地完成这些过程,并在编译和链接期间了解详细信息

  1. 将所有子框架Mach-O更改为静态库,这意味着将此目标编译为静态库(.a)
  2. 在构建阶段手动将所有子框架复制到UmbrellaFramework(与其他答案一样)
  3. 添加" FakeBundleShellScript" to Target" UmbrellaFramework",它使所有子框架将自己的资源打包为捆绑加入" UmbrellaFramework"
  4. 更改框架加载功能,您必须通过路径或网址加载子框架资源,因为它成为一个捆绑包,这一步意味着您应该对所有代码都具有最高控制权子框架&伞
  5. !!以下是" FakeBundleShellScript"你可以参考

    APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
    find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
    do
    FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
    FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
    BUNDLE_IN_ROOT="$APP_PATH/${FRAMEWORK_EXECUTABLE_NAME}.bundle"
    if [[ -e "$FRAMEWORK_EXECUTABLE_PATH" ]]; then
      FRAMEWORK_MACH_O="$(otool -a "$FRAMEWORK_EXECUTABLE_PATH" | head -n 1)"
      FRAMEWORK_FAT_ARCH="$(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")"
    else
      FRAMEWORK_MACH_O="NO EXIST"
      FRAMEWORK_FAT_ARCH="NO EXIST"
    fi
    echo "FRAMEWORK_EXECUTABLE_NAME is $FRAMEWORK_EXECUTABLE_NAME"
    echo "FRAMEWORK_EXECUTABLE_PATH is $FRAMEWORK_EXECUTABLE_PATH"
    echo "FRAMEWORK_MACH_O is $FRAMEWORK_MACH_O"
    echo "FRAMEWORK_FAT_ARCH is $FRAMEWORK_FAT_ARCH"
    echo "BUNDLE_IN_ROOT is $BUNDLE_IN_ROOT"
    if [[ "$FRAMEWORK_MACH_O" =~ "Archive :" ]]; then
      echo "Rmove Static-Mach-O is $FRAMEWORK_EXECUTABLE_PATH"
      rm "$FRAMEWORK_EXECUTABLE_PATH"
      defaults write "$FRAMEWORK/Info.plist" CFBundlePackageType "BNDL"
      defaults delete "$FRAMEWORK/Info.plist" CFBundleExecutable
      if [[ -d "$BUNDLE_IN_ROOT" ]]; then
        rm -rf "$BUNDLE_IN_ROOT"
      fi
      mv -f "$FRAMEWORK" "$BUNDLE_IN_ROOT"
    elif [[ "$FRAMEWORK_FAT_ARCH" =~ "Architectures in the fat file" ]]; then
      #statements
      EXTRACTED_ARCHS=()
      for ARCH in $ARCHS
      do
        echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
        lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
        EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
      done
      echo "Merging extracted architectures: ${ARCHS}"
      lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
      rm "${EXTRACTED_ARCHS[@]}"
      echo "Replacing original executable with thinned version"
      rm "$FRAMEWORK_EXECUTABLE_PATH"
      mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
    fi
    done
    

    http://alanli7991.github.io/2017/07/17/%E6%A8%A1%E5%9D%97%E5%8C%9617Framework%E4%B8%8EStaticFramework%E4%BC%AA%E8%A3%85Bundle/

    正如我所说的那样,关键是要做出一个不推荐的" UmbrellaFramework"是!!!! [将子框架编译为静态,通过假捆绑处理资源],记住!! Apple总是说DONT&T创建一个伞框架

    如果你能理解中文,更多细节可以制作一个" UmbrellaFramework"可以从我的博客

    获得

    Alan.li 2017年的文章

答案 2 :(得分:2)

添加到嵌入式库还会设置某些构建设置,从嵌入式库中删除库时不会将其删除。

Framework Search Paths很可能包含以前缺少的库的路径。

如果不以某种方式添加嵌入式库,它将无法工作。您可能希望使用一些依赖管理工具(如CocoaPods或Carthage)来为您完成更多或更少的工作。