【问题标题】:Creating a universal framework using Xcode 8?使用 Xcode 8 创建通用框架?
【发布时间】:2017-02-14 20:26:29
【问题描述】:

我公司的 iOS 框架旨在在真正的 iOS 设备上运行。所述框架目前作为 Xcode 项目中的附加目标生成,该项目也生成应用程序。 (这使得调试框架相对容易。)

我们最近收到要求也让它在模拟器中工作的请求。我现在可以这样做了,下一步是创建一个编译版本,它可以在真实设备和模拟器上运行。遗憾的是,我无法找到任何表明有人使用 Xcode 8 完成此操作的材料。有一些材料解释了如何使用旧版本的 Xcode,但在一个版本的 Xcode 中有效的方法可能在以后不起作用或不建议使用版本。 (我们已经有了一种创建通用框架中断的方法。)我尝试使用一些 Xcode 8 之前的脚本,但它们都不起作用。

有没有人设法使用 Xcode 8 为 iOS 生成通用框架?如果可以,怎么做?

提前感谢任何人提供的任何帮助。

亚伦·阿德尔曼

【问题讨论】:

标签: ios xcode ios-frameworks


【解决方案1】:

这是可能的,因为我目前正在 Xcode 8 上开发 iOS、watchOS 和 tvOS 上的通用框架。

我这样做的方式是创建一个聚合目标(跨平台)并在其构建阶段添加一个运行脚本。该脚本基本上为 iphonesimulator 和 iphoneos 编译 iOS 目标

在此之后它会创建一个新的二进制文件合并它们(lipo -create -output)

您是否介意发布您当前的构建脚本以生成通用框架,以便我可以指导您解决您做错了什么?

考虑到脚本在这里可能不是您的问题,您的问题可能是设置您的有效架构、您的架构,甚至是您如何签署目标。我现在建议不要选中目标的常规设置中的自动管理签名选项,并手动设置配置文件和证书。

运行脚本:

    #!/bin/sh

UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}/iOS"

# Step 1. Build Device and Simulator versions on iOS
xcodebuild -workspace "${PROJECT_NAME}.xcworkspace" -scheme "${PROJECT_NAME}"  -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6' clean build
xcodebuild -workspace "${PROJECT_NAME}.xcworkspace" -scheme "${PROJECT_NAME}" -sdk iphoneos clean build

# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/iOS"

# Step 3. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/iOS/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"

# Step 4. Convenience step to copy the framework to the project's directory
mkdir -p "${TMPDIR}/${PROJECT_NAME}/Frameworks/iOS"

cp -R "${UNIVERSAL_OUTPUTFOLDER}/iOS/${PROJECT_NAME}.framework" "${TMPDIR}/${PROJECT_NAME}/Frameworks/iOS"


# Step 6. Create .tar.gz file for posting on the binary repository
cd "${TMPDIR}"

# We nest the framework inside a Frameworks folder so that it unarchives correctly
tar -zcf "${PROJECT_NAME}.framework.tar.gz" "${PROJECT_NAME}/Frameworks/"
mv "${PROJECT_NAME}.framework.tar.gz" "${PROJECT_DIR}/"

# Step 7. Convenience step to open the project's directory in Finder
#open "${PROJECT_DIR}"

考虑到我在构建设置中将 Build Active Architecture Only 设置为 NO,有效的架构也设置为 arm64、x86_64、i386、armv7、armv7s。架构是 ${ARCHS_STANDARD} armv7s。

我还设置了用户定义的构建设置 BITCODE_GENERATION_MODE 位码。使用此构建设置,我确保生成启用了位码的二进制文件。

【讨论】:

  • 我没有当前的构建脚本,因为我尝试过的那些脚本都没有在 Xcode 8 中工作。
  • Build Failed due line 23: syntax error near unexpected token fi' line 23: fi' Command /bin/sh failed with exit code 2 Step 5 is missing and what is the purpose of "iphonesimulator -destination'platform =iOS Simulator,name=iPhone 6' clean build" 在脚本的Step1中。
  • @niczm25 我刚刚编辑过。关于目的地,它只是确保您使用 iPhone 6 为 iOS 编译。由于错误,目的地在 xcode7 上曾经是必需的。我不确定它是否仍然有必要。
  • @niczm25 我不确定是否有必要,但我总是对我的框架进行代码签名
  • 这是一个伟大而优雅的构建脚本,比我以前见过的要好得多。只是一些小建议。这假设工作空间与项目的名称相同;您可以使用 WORKSPACE_NAME := "${PROJECT_NAME}.xcworkspace 使其明确且可覆盖(通过自定义构建变量)。与库名称类似:- LIBRARY_NAME := ${PROJECT_NAME}
【解决方案2】:

构建 iOS/tvOS 通用/胖框架

https://github.com/unchartedworks/universalbuild

用法:

universalbuild (-p|--project name.xcodeproj) (-s|--scheme schemename) (-c|--configuration configurationname)

示例:

git clone https://github.com/cruisediary/Pastel.git
cd Pastel
universalbuild -p ./Pastel.xcodeproj -s Pastel -c Debug

【讨论】:

  • 看起来很有趣,但除非它适用于工作区,否则我不能给你 +1 :(
  • 不幸的是,它不能那样工作。在实现之前我做了一些研究,许多框架项目使用项目而不是工作区。所以它只支持 Xcode 项目。
【解决方案3】:

运行脚本创建通用框架(无递归问题)

#!/bin/sh

UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

# Next, work out if we're in SIM or DEVICE
if [ "false" == ${ALREADYINVOKED:-false} ]
then

export ALREADYINVOKED="true"

if [ ${PLATFORM_NAME} = "iphonesimulator" ]
then
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
else
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
fi

# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"

# Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi

# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"

# Step 5. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"

# Step 6. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"

fi

【讨论】:

    【解决方案4】:

    我也在同样的问题上苦苦挣扎。我有一系列用作源 pod 的 cocoapod,但需要转换为二进制 pod。在大量的谷歌搜索、反复试验和黑客攻击之间,我想出了一个我取得了巨大成功的脚本。它基于您在此处看到的脚本,但在缺少某些内容时重构为函数和一些调试输出(进入 /tmp 中的日志)。

    该脚本可以在此处作为 github 要点找到:https://gist.github.com/intere/bc380fa45ccf23976d3fc297522d29a8

    FWIW,我一直在使用 Xcode 9(9.2,然后是 9.3,现在是 9.4)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-01
      • 2013-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-10
      相关资源
      最近更新 更多