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

 flyfish6300_468 发布于 2023-01-11 17:26

我正在尝试为iOS应用程序制作动态框架.感谢新版本的Xcode(6),我们可以在创建新项目时选择Cocoa Touch Framework,不再需要添加聚合目标,运行脚本等等.构建框架时我没有问题.但是当我尝试在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应用程序项目做了同样的事情,但没有任何作用.我觉得有些事我不明白.

例如,当我仅使用命令行"xcrun lipo -info MyFramework"检查i386(iOS模拟器)的框架时,我遇到了一个问题

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

如果有人可以帮助我获得适用于所有iOS架构(包括模拟器)的框架.

5 个回答
  • 我这样做的方式类似于vladof,但希望有点简单.我将框架作为app项目的子项目.

    框架项目

    创建一个新的iOS Cocoa Touch Framework.称之为MyLib.这将创建一个MyLib.h

    添加一个简单的Cocoa Touch Obj-C类,MyClass(.h​​和.m),并在.m的实现中,创建一个返回字符串的方法, - (NSString*)greetings;

    在MyLib.h中,在底部附近添加#import"MyClass.h"

    在目标的Build Phases/Headers部分中,将MyClass.h从Project部分移动到Public部分.

    做一个构建(cmd-B)

    关闭项目

    应用项目

    创建一个新的单视图应用程序项目,Swift或Obj-C.称之为MyApp.

    从Finder中,将MyLib项目文件拖到MyApp窗口的左侧管理器部分,并确保插入行位于MyApp下方.这使得MyLib成为MyApp的子项目.(它仍然可以在其他项目中以相同的方式使用)

    单击组织器中的MyApp,然后选择MyApp目标并选择Build Phases.

    在Tar​​get Dependancies中,单击+号并添加MyLib.

    在Link with Libraries中,单击+号并添加MyLib.framework.

    对于Obj-C应用程序

    在ViewController.m中,添加#import

    在viewDidLoad中,添加以下行:

    MyLib*x = [[MyLib alloc] init];

    NSLog(@"%@",x.greetings);

    运行该项目,您应该在调试窗口中看到该消息. -

    对于Swift应用程序

    在ViewController.swift中,添加import MyLib

    在viewDidLoad中,添加以下行:

    var x:MyLib = MyLib()

    println("(x.greetings())") -

    通过这种方式,应用程序依赖于框架,因此如果您在框架类中进行更改,则不必更改目标以单独构建框架,它将首先编译框架,然后是应用程序.

    2023-01-11 17:27 回答
  • 基于所有的响应,上raywenderlich.com岗位和要旨所创造克里斯·康威我想出了这个.

    执行以下步骤,我能够构建一个Cocoa Touch框架(包括Swift和Objective-C文件),其中包含模拟器和设备的所有体系结构:

      在框架的项目中创建一个新的(聚合)目标

      在"Build Phases"下,选择"Add Run Script"并复制该文件的内容

      选择总目标方案选择下拉

      构建目标 总方案

    希望能帮助到你 :)

    更新:修复了步骤#3中路径不正确的要点中的错误.感谢Tokuriku !!

    更新 在Xcode 7和8中,单击文件>新建>目标...然后选择"其他"组以选择聚合目标

    2023-01-11 17:27 回答
  • 以下是创建胖(通用)框架的步骤:

      设置ONLY_ACTIVE_ARCH=NOBuild Settings项目中.

      为模拟器构建库

      为设备构建库

      Products框架的控制台文件夹中 打开(可以通过打开框架文件夹打开它,然后cd ..从那里打开)

    在此输入图像描述 在此输入图像描述

      从文件夹运行此脚本Products.它在此文件夹中创建fat Framework.(或按照以下4中的说明手动完成.5.)

      framework_name="${$(basename $(find ./Debug-iphoneos -type d -name '*.framework' -maxdepth 1))%.*}" && \
      cp -R Debug-iphoneos/$framework_name.framework ./$framework_name.framework && \
      lipo -create -output "$framework_name.framework/$framework_name" "Debug-iphonesimulator/$framework_name.framework/$framework_name" "Debug-iphoneos/$framework_name.framework/$framework_name"
      


    要么:

      通过此脚本使用lipo组合这两个框架(替换YourFrameworkName为您的框架名称)

      lipo -create -output "YourFrameworkName" "Debug-iphonesimulator/YourFrameworkName.framework/YourFrameworkName" "Debug-iphoneos/YourFrameworkName.framework/YourFrameworkName"
      

      替换为现有框架的新二进制文件:

      cp -R Debug-iphoneos/YourFrameworkName.framework ./YourFrameworkName.framework
      mv YourFrameworkName ./YourFrameworkName.framework/YourFrameworkName
      


      利润:./YourFrameworkName.framework- 是现成的胖二进制!您可以将其导入您的项目!


    对于项目,不在xcworkspace-es中:

    您也可以尝试使用这个要点但似乎它不适用于工作空间中的项目.

    2023-01-11 17:27 回答
  • 我已经改变了某人的脚本以支持所有Simulator的架构:

    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}"
    

    2023-01-11 17:27 回答
  • 请尝试以下步骤来创建包含框架项目和应用程序项目的工作区.

    工作区:

    创建工作区.

    框架项目:

    在Workspace中创建一个iOS Cocoa touch Framework项目.

    添加一个简单的Objective C类MyClass(头.h和实现文件.m),并创建一个方法- (void)问候语.

    转到项目构建阶段 > 标题 >将MyClass.hProject移动到Public.

    将方案更改为框架项目并选择iOS模拟器,然后构建.(如果集成此框架的应用程序在设备上运行,请选择iOS设备.我将继续在此示例中使用模拟器)

    您应该没有问题构建,框架构建可以在您的派生数据目录中找到,您可以在管理器中找到它.

    应用项目:

    在Workspace中创建Swift Single View应用程序.

    将iOS模拟器框架构建(在Debug-iphonesimulatorRelease-iphonesimulator中找到)拖到项目上方.

    创建一个桥接头来向Swift公开Objective C类方法.

    在桥接头文件中导入MyClass.h.

    请注意,如果找不到MyClass定义,则添加框架Headers路径到Build Settings Header Search Paths.

    ViewController.swift的 viewDidLoad中创建MyClass的实例,然后调用问候语.

    将框架添加到Target> Embedded Binaries

    将方案更改为app project并选择iOS模拟器,然后构建.

    您应该能够看到问候消息.

    请注意,上面的示例演示了如何构建在模拟器中运行的应用程序.如果您需要创建在模拟器设备上运行的通用静态库,那么一般步骤如下:

    模拟器构建库

    设备构建库

    使用lipo将它们结合起来

    有关于它在网络上很好的参考,在这里的例子.

    为框架创建通用二进制文件:导航到框架Derived Data目录然后/ 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是我的框架项目名称.

    2023-01-11 17:28 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有