2016-01-19 28 views
11

我在Swift中构建了一个框架。该框架使用Cocoapods,其中一个豆荚是用Objective C编写的。Swift fat framework with Objective-C Cocoapod

我还使用自定义脚本使框架成为一个胖框架,因此它支持32/64位系统。 (这将运行在该项目的一个单独的目标,我想知道是否有什么关系呢?)

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

if [ "true" == ${ALREADYINVOKED:-false} ] 
then 
echo "RECURSION: Detected, stopping" 
else 
export ALREADYINVOKED="true" 

// Step 1. Build Device and Simulator versions 
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build 
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" 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}/" 

// Step 3. Copy Swift modules (from iphonesimulator build) to the copied framework directory 
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule" 

// 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 

当我创建这个胖子框架,并把它变成一个项目,我想使用它在编译器上总是失败b/c该项目无法看到目标C cocoa pod模块。

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

当我更改构建平台时,找不到任何体系结构。

任何解决方案,我可以生成一个框架,我可以在一个单独的Xcode项目中使用(对于所有iOS或OS X)将是非常棒的。

回答

0

显然你错过了模拟器的64位体系结构。

当您从Xcode构建目标时,取决于您选择了哪种模拟器 - 生成的库将分别包含选定的32位或64位版本模拟器的i386或x86_64。

我想,cli版本只生产i386版本。

你可以尝试设置架构的脚本:

xcodebuild -target "${PROJECT_NAME}" ARCHS="i386 x86_64" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

作为替代方案,您可以尝试使用64位模拟器(iPhone 5S +)手工打造,然后提取丢失的架构,然后使用lipo命令将其放入最终库。

+0

我相信这是由ONLY_ACTIVE_ARCH = NO参数照顾的。除此之外,它也适用于没有Objective-C可可豆荚的情况。 –

3

使用CocoaPods时,您不能运行xcodebuild-target。当您使用-target时,Xcode将只考虑活动项目,并且无法拉入Pod依赖项,类似于您只是在Xcode中打开项目文件并尝试构建。

您应该运行xcodebuild -workspace "${PROJECT_NAME}.xcworkspace" -scheme "${PROJECT_NAME}" ...,假设CocoaPods生成了工作区,并且Xcode使用目标名称生成了一个方案。如果在其他设备上运行,您还需要确保您的方案标记为共享。

一旦你的框架建成,你将需要在它将使用它的应用程序中包含它和它依赖于的框架。对于您的框架,这意味着将其包含在“常规”>“嵌入式二进制文件”和“常规”>“链接的框架和库”中。对于您所依赖的框架(例如AlamoFire),您可以指导用户将其包含在其Podfile中,您可以将其打包并随框架一起发布,或者可以同时执行这两个操作并让用户执行适合他们的操作。

+0

会有什么我需要做或改变?我没有得到一个关于它没有找到一个模块的编译器错误,但当我尝试运行任何我得到的:〜/ Library/Developer/CoreSimulator/Devices/74636985-3538-4693-B131-983106003055/data/Containers/Bundle/Application/FBC92D11-240D-45BB-9F21-C4372DE509B4/TestMyKit.app/TestMyKit 原因是:image not found (lldb) –

+0

这是完全错误吗?没有关于它无法加载的图像的信息?这两个库中列出的.framework链接和二进制文件以嵌入到该应用程序中? –

+0

这是完整的错误:dyld:Library not loaded:@ rpath/Alamofire.framework/Alamofire 引用自:〜/ Library/Developer/CoreSimulator/Devices/74636985-3538-4693-B131-983106003055/data/Containers/Bundle /Application/FFC6E8DA-4877-4142-A97B-73A3B7712319/TestMyKit.app/Frameworks/DICAPIKit.framework/DICAPIKit 原因:找不到图像 (lldb) - 是的框架既是链接的又是嵌入的。 –