iOS-制作Framework(最新)

作者: 陈向阳哈 | 来源:发表于2015-12-31 09:06 被阅读10866次

    前言

    之前有很多的大神们已经写过framework的制作,但最近由于Xcode7的出现,很多之前的教程内容已经不符,对于初学者来说,找到一篇能够直接明了,简单易学的制作framework的文章比较困难。本文将基于Xcode7创建一个简单的工程,通过两种方法来教大家如何制作一个自己的framework。

    简介

    Mac OS X扩展了framework的功能,让我们能够利用它来共享代码和资源。通过framework我们可以共享所有形式的资源,如动态共享库,nib文件,图像字符资源以及文档等。
    系统会在需要的时候将framework载入内存中,多个应用程序可以同时使用同一个framework。这种方法可以使得你的代码易分享,在多个工程中复用,并且可以隐藏实现细节,控制公开的头文件。

    制作

    步骤

    • 打开Xcode,创建新工程。手下留情,请先看图!
    创建Cocoa Touch Framework
    • 创建功能类。这里我创建一个继承自NSObject的SayHello类
    • 在新创建的类里面声明方法并实现。这里我写一个
      sayHello的方法,以便后面测试使用。

      SayHello.h

      #import <Foundation/Foundation.h>
      @interface SayHello : NSObject
      -(void)sayHello;
      @end    
      

      SayHello.m

       #import "SayHello.h"
      @implementation SayHello
      -(void)sayHello
       {
        NSLog(@"你好,第一次见面,请多关照");
       }
       @end
      
    • 在TARGETS下选中工程,在Build Settings下更改几个参数。

      更改参数

    在Architectures下增加armv7s,并选中。将Build Active Architecture Only 设置为NO。

    添加armv7s
    • 设置Headers

      将你要公开的头文件移动到Public下,要隐藏的放在Private或者Project下,当然,隐藏的头文件就无法再被引用。


      设置headers

      然后需要在Test.h(必须是公开的,否则无法引用)中将你所有要公开的.h引入。

      引入头文件
      • 打包framework

      • 方法一

        1.选中模拟器,编译程序

        2.选中测试机,编译程序

        3.在finder中找到framework文件

        framework

        选中图中所标示的framework,然后右键show in finder。
        找到下图中所示的Test文件,一个是Debug-iphoneos(真机)下的,一个是Debug-iphonesimulator(模拟器)下的。

        frameworkTest

        4.通过终端命令将两个framework合为一个模拟器和真机都可使用的framework。

        打开控制台输入 lipo -create iphoneos下frameworkTest的路径 simulator下frameworkTest的路径 -output 新的路径,这样就完成了模拟器和真机版本的合并,新路径下的frameworkTest就是你合并后的文件,将这个文件名字改成和你未合并之前的Test一样的名字,放到framework文件夹下,替换掉原来的frameworkTest文件。

        合并命令

        上面这段命令就是把真机和模拟器的frameworkTest合并成一个MyNewFrameworktest文件并存放在桌面上的New文件夹下。

        文件替换

        5.将修改后的framework拷贝出来保存,这就是我们最终制作的framework。

      • 方法二

        1.选中TARGETS下的工程,点击上方的Editor,选择Add Target创建一个Aggregate.

        Add Taget
        选择Other下的Aggregate,点击Next创建。 Aggregate

        2.嵌入脚本。选中刚刚创建的Aggregate,然后选中右侧的Build Phases,点击左下方加号,选择New Run Script Phase

        New Run Script Phase
        将这段脚本复制进去。
        
        ```
        

        Sets the target folders and the final

        framework product.
        

        如果工程名称和Framework的Target名称不一样的

        话,要自定义FMKNAME
        

        例如: FMK_NAME = "MyFramework"

        FMK_NAME=${PROJECT_NAME}

        Install dir will be the final output to

               the framework.
        

        The following line create it in the root

                folder of the current project.
        

        INSTALL_DIR=${SRCROOT}/Products/$
        {FMK_NAME}.framework

        Working dir will be deleted after the

               framework creation.
        

        WRK_DIR=build
        DEVICE_DIR=${WRK_DIR}/Release-iphoneos/$
        {FMK_NAME}.framework
        SIMULATOR_DIR=${WRK_DIR}/Release-
        iphonesimulator/${FMK_NAME}.framework

        -configuration ${CONFIGURATION}

        Clean and Building both architectures.

        xcodebuild -configuration "Release" -target
        "${FMK_NAME}" -sdk iphoneos clean build
        xcodebuild -configuration "Release" -target
        "${FMK_NAME}" -sdk iphonesimulator clean
        build

        Cleaning the oldest.

        if [ -d "${INSTALL_DIR}" ]
        then
        rm -rf "${INSTALL_DIR}"
        fi
        mkdir -p "${INSTALL_DIR}"
        cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"

        Uses the Lipo Tool to merge both binary

           files (i386 + armv6/armv7) into one     
        

        Universal final product.
        lipo -create "${DEVICE_DIR}/${FMK_NAME}"
        "${SIMULATOR_DIR}/${FMK_NAME}" -output "$
        {INSTALL_DIR}/${FMK_NAME}"
        rm -r "${WRK_DIR}"
        open "${INSTALL_DIR}"

         ![嵌入脚本](https://img.haomeiwen.com/i962036/2547ce4cef2d12df.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)     
         *3.编译。如图所示,command+B编译。*
        
        ![编译](https://img.haomeiwen.com/i962036/7e46c5210af825ba.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 
         *4.在finder中找到framework,拷贝出来。*
        
        
    • 使用制作完成的framework

      直接将你制作出来的framework添加到要使用的工程里,在需要使用的文件里引入头文件,使用framework中的功能类。如下图


      使用

    提醒

    1.在制作framework或者lib的时候,如果使用了category,则使用改FMWK的程序运行时会crash,此时需要在该工程中 other linker flags添加两个参数 -ObjC -all_load.

    2.带有图片资源的需要把图片打包成Bundle文件,和framework一起拷贝到相应的项目中。

    3.公开的类中如果引用的private的类,打包以后对外会报错,找不到那个private的类,可以把那个private的.h放到

    结言

    现在,相信你已经可以按照文档步骤制作出一个framework,相信过程中可能还会遇到一些问题,希望大家能够把这些问题记录并整理,将这些经验分享出来。也欢迎大家联系、讨论。
    最后,希望大家能完成带有图片资源的Bundle的制作。

    Try your best!

    相关文章

      网友评论

      • 爱吃麦子的鱼:你好,想问一下怎么添加图片资源啊,可不可以详说一下啊
        爱吃麦子的鱼:@陈向阳哈 我弄好了,谢谢
        陈向阳哈:@_安然i 把图片先单独打包成bundle
      • hard_coder:我使用脚本打包报错xcodebuild will download missing or updated provisioning profiles. Requires a developer account to have been added in Xcode's Accounts preference pane.
        -allowProvisioningDeviceRegistration Allow xcodebuild to register your destination device on the developer portal if necessary. This flag only takes effect if -allowProvisioningUpdates is also passed.
        /Users/xuxuli/Library/Developer/Xcode/DerivedData/xuli.framework-bdgpbhqtxgsingedtyrscmnadokn/Build/Intermediates.noindex/xuli.framework.build/Debug-iphoneos/xuli.build/Script-63B7D76F2029814800A6475B.sh: line 18: if[-d/Users/xuxuli/Desktop/demo演练/xuli.framework/Products/.framework]: No such file or directory
        /Users/xuxuli/Library/Developer/Xcode/DerivedData/xuli.framework-bdgpbhqtxgsingedtyrscmnadokn/Build/Intermediates.noindex/xuli.framework.build/Debug-iphoneos/xuli.build/Script-63B7D76F2029814800A6475B.sh: line 19: syntax error near unexpected token `then'
        /Users/xuxuli/Library/Developer/Xcode/DerivedData/xuli.framework-bdgpbhqtxgsingedtyrscmnadokn/Build/Intermediates.noindex/xuli.framework.build/Debug-iphoneos/xuli.build/Script-63B7D76F2029814800A6475B.sh: line 19: `then'
        是什么原因呢楼主
        陈向阳哈:重新生成一个
        hard_coder:@陈向阳哈 我描述文件该怎么写呢,我就直接copy过去啦呀
        陈向阳哈:@hard_coder 你的描述文件有问题
      • 瞬间看见永远:你好,Aggregate打包制作的库,里面什么都没有
      • 小红帽168:楼主写的文章帮大忙了,谢谢!请问release方法也是相同么
        陈向阳哈:@小红帽168 你是指发布版本吗?这个是两种环境都支持的打包方式
      • 一蓑丨烟雨:感谢大神的分享
        陈向阳哈:@Gold丶Silence 称不上大神:smile:
      • toplee:怎么限制生成framework的ios版本,是支持ios7还是最低ios8?
      • Crassus:使用命令那个生成framwork,在github上支持xcode8.3.2
        #!/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}"
      • humanff:请问framework里面的xib文件直接配置图片文件名,打包好后测试会报这个错误
        Could not load the "tick_btn" image referenced from a nib in the bundle with identifier "cmcc.testLayer" 应该怎么解决
        就是直接打开xib配置图片名,应该怎么写,才能让程序读取出来
        就是说不写bundle有可能实现么
      • 我叫阿水:为什么都是只写debug版的,那release版的呢?
      • fuccccck_iOS:提醒的第三句话,你没有写完整啊。还有 我的framework写完以后,放到其他工程 老是报错说 count not build module,有木有解决方法啊??
      • 十六_:大神请问我的framework里面还有许多他的三方framework 比如说支付分享等。我怎么一起打包进去framework呢?
      • LByy:我的按照第二种打包framework 都编译成功了 。但是 没有找到啊?那个 $文件 里面没有framework 包啊 在线等急
      • SuperMarioGG:您好,自己的framework中使用了分类,是在制作framework时添加两个参数还是在使用framework的项目中添加
        陈向阳哈:@caimterZhu 在你使用的那个工程里加就行了
        SuperMarioGG:@陈向阳哈 就是类别
        陈向阳哈:@caimterZhu 不太理解什么分类
      • f4295b801f39:太棒了,就需要这样简洁明了的
      • 古斯比德:楼主你最后贴得shell脚本完全是一团糟啊
        钱刀为:简直是一大团糟糕
      • mf168:我想打包请求类文件 里面带有Pods 的AFNetworking 怎么弄?
      • volientDuan:脚本运行出错怎么解决
      • 2a687b34d296:写的非常好, 谢谢分享
      • 牵线小丑:swift 语言的怎么弄呢
        牵线小丑:@陈向阳哈 用脚本编译的时候提示错误,你知道怎么解决么,xcode 7。google了也没解决。
        牵线小丑:@陈向阳哈 fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: can't open input file: /Users/oyc/Library/Developer/Xcode/DerivedData/SNetCLib-avdnmwubjbmrizbgczwknhoutfes/Build/Products/Release-iphoneos/Combine.framework/Combine (No such file or directory)
        陈向阳哈:@牵线小丑 使用桥接 然后用swift 直接编程就行了
      • 程序猿小武:Could not build module 'IM30CSKit' IM30CSKit是我自己写的一个Framework ,按照大神您的教程一步步走下来的,里面有XIB,image,但是一直提示我这个问题- -!不知道您有没有解决办法
        陈向阳哈:@潇武子 需要打包个Bundle
      • 往事如烟熏三文鱼:大神呐,你是从哪里学来的?不看你的文章都不知道怎么做。。。

      本文标题:iOS-制作Framework(最新)

      本文链接:https://www.haomeiwen.com/subject/fcgihttx.html