Xcode 6 iOS创建Cocoa Touch框架-体系结构问题

Xcode 6 iOS创建Cocoa Touch框架-体系结构问题,cocoa,ios8,xcode6,dynamic-library,ios-universal-framework,Cocoa,Ios8,Xcode6,Dynamic Library,Ios Universal Framework,我正在尝试为iOS应用程序创建一个动态框架。由于Xcode(6)的新版本,我们可以在创建新项目时选择Cocoa Touch框架,而无需再添加聚合目标、运行脚本等。我在构建框架时没有任何问题。但当我试图在iOS应用程序中使用它时,我会遇到一些架构问题 ld: warning: ignoring file /Library/Frameworks/MyFramework.framework/MyFramework, file was built for x86_64 which is not the

我正在尝试为iOS应用程序创建一个动态框架。由于Xcode(6)的新版本,我们可以在创建新项目时选择Cocoa Touch框架,而无需再添加聚合目标、运行脚本等。我在构建框架时没有任何问题。但当我试图在iOS应用程序中使用它时,我会遇到一些架构问题

ld: warning: ignoring file /Library/Frameworks/MyFramework.framework/MyFramework, file was built for x86_64 which is not the architecture being linked (arm64): /Library/Frameworks/MyFramework.framework/MyFramework
Undefined symbols for architecture arm64:
  "_OBJC_CLASS_$_MyFrameworkWebService", referenced from:
      objc-class-ref in AppDelegate.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

ld: warning: ignoring file /Library/Frameworks/MyFramework.framework/MyFramework, file was built for x86_64 which is not the architecture being linked (armv7): /Library/Frameworks/MyFramework.framework/MyFramework
Undefined symbols for architecture armv7:
  "_OBJC_CLASS_$_MyFrameworkWebService", referenced from:
      objc-class-ref in AppDelegate.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我尝试更改框架项目和目标的设置(架构&仅构建有效架构&有效架构)。我也为iOS应用程序项目做了同样的事情,但没有任何效果。我想有些事我不明白

例如,当我仅为i386(iOS模拟器)构建框架时,请使用命令行检查 “xcrun lipo-info MyFramework”,我有一个问题

ld:警告:忽略文件/Library/Frameworks/MyFramework.framework/MyFramework,该文件是为x86_64构建的,它不是要链接的体系结构(i386)


如果有人能帮助我获得一个适用于所有iOS架构(包括模拟器)的框架。

尝试以下步骤创建一个包含框架项目和应用程序项目的工作区

工作空间:

  • 创建一个工作区
框架项目:

  • 在工作区内创建iOSCocoa touch框架项目
  • 添加一个简单的Objective C类MyClass(header.h和implementation file.m),并创建一个方法-(void)问候语
  • Go project构建阶段标题>将MyClass.h从项目移动到公共
  • 将方案更改为框架项目,选择iOS模拟器,然后构建。(如果集成此框架的应用程序在设备上运行,请选择iOS设备。在本例中,我将继续使用模拟器)
  • 您应该没有问题构建,框架构建可以在您的派生数据目录中找到,您可以在管理器中找到
应用程序项目:

  • 在工作区内创建Swift单视图应用程序
  • 将iOS模拟器框架构建(在调试iphonesimulator或发布iphonesimulator中找到)拖到项目上方
  • 创建桥接头以向Swift公开目标C类方法
  • 在桥接头文件中导入MyClass.h
  • 请注意,如果找不到MyClass定义,则将的框架路径添加到构建设置头搜索路径
  • 在ViewController.swift的viewDidLoad中创建MyClass的实例,然后呼叫问候语
  • 将框架添加到目标>嵌入式二进制文件
  • 将scheme更改为app project并选择iOS模拟器,然后构建
  • 您应该能够看到问候语
请注意,上面的示例演示了如何构建在模拟器中运行的应用程序。如果需要创建在模拟器和设备上运行的通用静态库,则一般步骤如下:

  • 建立模拟器库
  • 为设备构建库
  • 使用lipo将它们组合起来
例如,网上有很多关于它的参考资料

为框架创建通用二进制文件:导航到框架派生数据目录,然后/Build/Products,以下命令应帮助您在Products目录中创建通用二进制文件:

lipo -create -output "framework-test-01-universal" "Debug-iphonesimulator/framework-test-01.framework/framework-test-01" "Debug-iphoneos/framework-test-01.framework/framework-test-01" 

请注意,framework-test-01是我的框架项目名称。

我这样做的方式与vladof类似,但希望简单一点。我将框架作为应用程序项目的一个子项目

框架项目

  • 创建新的iOS Cocoa Touch框架。称之为MyLib。这将创建一个MyLib.h
  • 添加一个简单的Obj-C类MyClass(.h&.m),并在.m的实现中创建一个返回字符串的方法,-(NSString*)
  • 在MyLib.h中,将其添加到底部附近,#导入“MyClass.h”
  • 在目标的buildphases/Headers部分,将MyClass.h从Project部分移动到Public部分
  • 进行构建(cmd-B)
  • 关闭该项目
应用程序项目

  • 创建一个新的单视图应用程序项目,Swift或Obj-C。称之为MyApp
  • 从Finder中,将MyLib项目文件拖动到MyApp窗口的左侧组织者部分,并确保插入线正好位于MyApp下方。这使MyLib成为MyApp的子项目。(在其他项目中仍然可以使用相同的方法)
  • 单击组织者中的MyApp,然后选择MyApp目标并选择构建阶段
  • 在目标相关性中,单击+号并添加MyLib
  • 在“与库的链接”中,单击+号并添加MyLib.framework
对于Obj-C应用程序

  • 在ViewController.m中,添加#导入
  • 在viewDidLoad中,添加以下行:
  • MyLib*x=[[MyLib alloc]init]
  • NSLog(@“%@”,x.0)
  • 运行项目,您应该会在调试窗口中看到消息。-
对于一个快速的应用程序

  • 在ViewController.swift中,添加导入MyLib
  • 在viewDidLoad中,添加以下行:
  • 变量x:MyLib=MyLib()
  • println(“(x.问候语())”)-

通过这种方式,应用程序依赖于框架,因此如果您更改框架类,则不必更改单独构建框架的目标,它只需首先编译框架,然后是应用程序。

围绕vladof共享的方法,有几个更适用于基于swift的框架的附加点

  • 关联链接中的脚本需要修改,以便从iphonesimulator和iphoneos复制所有文件,因为swift为arm和i386提供了单独的编译文件
  • 埃苏
    #!/bin/sh
    
    UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
    
    # make sure the output directory exists mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
    
    # 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}"
    
    UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
    
    # make sure the output directory exists
    mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
    
    # 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}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator VALID_ARCHS="x86_64 i386" BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
    
    # Step 2. Copy the framework structure to the universal folder
    cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
    
    # Step 3. 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 4. Convenience step to copy the framework to the project's directory
    cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
    
    # Step 5. Delete temporary build directory in the project's directory
    rm -rf "${PROJECT_DIR}/build"
    
    # Step 6. Convenience step to open the project's directory in Finder
    open "${PROJECT_DIR}"
    
    lipo -create -output [MyFrameworkProject].framework/[MyFrameworkProject] [MyFrameworkProject].framework/MyFrameworkProject [MyFrameworkProject]_sim.framework/MyFrameworkProject