iOS制作framework

作者: 纪小衰 | 来源:发表于2016-09-13 22:46 被阅读2014次

    转载请注明出处:

    http://www.jianshu.com/p/04a7e28f11b9

    作者:纪小衰

    framework的使用十分方便,一般来说直接拖入到项目中就可以直接使用接口,而不用在意具体的实现细节,对于功能的封装是个很好的途径。当我们写的工具给别人使用的同时又不想让别人知道自己的代码,这个时候使用framework就可以派上用场了(ps:个人觉得开源是一个大牛必须要体会到的思想)。。。

    废话不多说,xcode如今已经到了7,对于framework的制作可以说是十分方便了。公司之前的framework的制作都是采用执行纯脚本的方法,可以直接命令行编译和融合不同版本(模拟器,真机,debug,release)的framework,个人不是很喜欢,还是喜欢用较为官方的方式来制作framework,当然为了方便还是少量地参照了网上的一些脚本。

    一、新建framework工程

    xcode->file->new->project选中iOS下的cocoa touch framework->next

    创建工程

    接下来的步骤和创建一个普通的工程没什么区别,创建完毕以后在工程中新建JRModel类和JRModel2类文件,在我们的framework工程创建以后系统会默认创建一个和工程名相同的头文件,我这里是JRDataModel.h。一般来说我们会把framework中需要提供给外部的头文件都在这个头文件中import一下,这样使用者只要包含一个头文件就可以使用所有的类了。

    创建文件后导入公共头文件

    这个地方需要注意到两点,一个就是导入的时候必须要使用framework的方式导入,使用<包名/头文件名.h>,因为在实际使用framework的时候是需要从包中搜索头文件的。还有一个坑就是右边的那个设置,对于总的头文件还有所有需要用到的头文件,都需要公开,选中以后把右边包的编译属性改为public,否则打出来的包在别的工程中实际上是不能引用的。

    二、编译工程

    接下来就是开始编译工程了(如下图),选中运行按钮右边的编译目标,选择Generic iOS Device,然后command+b编译一下,这个时候我们工程中的products文件夹下面的framework文件会由原来的红色(表示文件丢失)变成黑色(表示文件存在)。如果我们选择的是Generic iOS Device那么编译出来的framework只能在真机中使用,如果选中的是普通的模拟器,那么编译出来framewo只能在模拟器中使用。

    tips:这里需要注意一下,如果一开始选择的是模拟器,那么即使build成功,framework也不会变成黑色,可能是因为这里的framework指向的是真机中对应的framework,但是在相对应的目录下的模拟器对应的framework是存在的

    编译framework

    右击生成好的framework,选中show in finder可以查看framework在磁盘中的位置。进入目录以后,一般来说最多有四个目录,我这里只有三个(如下图)因为对于模拟器一般不会要release版本的。也可以通过finder,快捷键control+command+g输入~/Library/Developer/Xcode/DerivedData/Build/Products默认路径进入

    分别在模拟器和真机选项中编译,发现实际只产生了模拟器和真机的debug版本的framework包,而没有release版本的包。这需要我们调整一下xcode的build类型,选中运行的target在下来列表中选Edit Scheme,进入以后把run中的Build Configureation修改为Release,这时候就可以编译出release版本的包了(如下图)

    三、合并framework

    到此,我们已经制作出对于各种情况下使用的framework了,对于不同的环境需要使用不同种类的framework,这在很多时候显得很麻烦。能不能制作一个能在所有场景使用的包呢。

    这个时候我们可以考虑合并所有版本的包,一般来说可以使用脚本进行合并,但是每次使用脚本比较麻烦,我们可以在xcode中添加一个共同体aggregate,然后添加编译脚本来实现。

    在工程中点击上方工具栏File->New->Target,在选项中选择Other中的Aggregate,命名最好和工程名有关,我这里就写成JRDataModelAggregate。

    新建Aggregate

    新建好以后,选择targets列表下的JRDataModelAggregate,点击build phases,点击+新建一个New Run Script Phase,把下面的脚本复制到shell下的选项中(脚本来源自网络,感谢这段脚本的原作者)。有能力的可以根据自己的需要修改下面的脚本。

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

    粘贴shell脚本

    复制完以后,点击左上角运行旁边的target(上图左上角那个黄色的选项),在下拉的列表中选中我们刚才创建的JRDataModelAggregate,command+B编译一下,如果没什么意外,等到编译成功便会弹出我们编译好的framework了。

    四、验证framework

    framework其实可以看做是一个带扩展名的文件夹,所以我们可以直接进入framework的内部。通过下面的控制台指令进入到framework中(cd后面是你自己的framework路径)

    cd /Users/ctzxh/Desktop/JRModel/JRDataModel/Products/JRDataModel.framework

    执行下面的命令判断当前framework支持的架构

    lipo -info JRDataModel

    完成验证

    Tips1:

    对于上面的每种处理器架构对应的设备请自行百度。这里说明一下,如果让你的包可以支持armv7s的架构(这里说的支持指的是针对这种架构的优化),可以根据下图的方式添加,新版的xcode默认便没有加上armv7s的架构,由于处理器向下兼容,所以即使不添加,所使用包的工程也是可以在armv7s架构上的机器运行的。个人推荐还是不必考虑了,按照官方的来就可以了。添加完以后在验证包的时候会多显示一个armv7s。

    添加armv7s架构

    Tips2:

    上面用Aggregate制作的库是拖入到使用的工程是直接可以使用的,但是之前分别制作的库直接拖入是不能使用的,解决的方式有两种:

    第一种:制作链接库的时候,选择生成静态库

    第二种:在使用动态链接库的时候嵌入二进制库,在下面的选项中添加要导入的动态库

    网上有种方式是把framework的属性从required变成Optional,亲测行不通,能导入但是不能用。。。

    就到这儿吧~~~

    Add:如果只做的是.a的静态库可以使用下面的脚本,方法一样

    if["${ACTION}"="build"]

    then

    #要build的target名

    target_Name=${PROJECT_NAME}

    echo"target_Name=${target_Name}"

    #build之后的文件夹路径

    build_DIR=${SRCROOT}/build

    echo"build_DIR=${build_DIR}"

    #真机build生成的头文件的文件夹路径

    DEVICE_DIR_INCLUDE=${build_DIR}/Release-iphoneos/include/${PROJECT_NAME}

    echo"DEVICE_DIR_INCLUDE=${DEVICE_DIR_INCLUDE}"

    #真机build生成的.a文件路径

    DEVICE_DIR_A=${build_DIR}/Release-iphoneos/lib${PROJECT_NAME}.a

    echo"DEVICE_DIR_A=${DEVICE_DIR_A}"

    #模拟器build生成的.a文件路径

    SIMULATOR_DIR_A=${build_DIR}/Release-iphonesimulator/lib${PROJECT_NAME}.a

    echo"SIMULATOR_DIR_A=${SIMULATOR_DIR_A}"

    #目标文件夹路径

    INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}

    echo"INSTALL_DIR=${INSTALL_DIR}"

    #目标头文件文件夹路径

    INSTALL_DIR_Headers=${SRCROOT}/Products/${PROJECT_NAME}/Headers

    echo"INSTALL_DIR_Headers=${INSTALL_DIR_Headers}"

    #目标.a路径

    INSTALL_DIR_A=${SRCROOT}/Products/${PROJECT_NAME}/lib${PROJECT_NAME}.a

    echo"INSTALL_DIR_A=${INSTALL_DIR_A}"

    #判断build文件夹是否存在,存在则删除

    if[ -d"${build_DIR}"]

    then

    rm -rf"${build_DIR}"

    fi

    #判断目标文件夹是否存在,存在则删除该文件夹

    if[ -d"${INSTALL_DIR}"]

    then

    rm -rf"${INSTALL_DIR}"

    fi

    #创建目标文件夹

    mkdir -p"${INSTALL_DIR}"

    #build之前clean一下

    xcodebuild -target${target_Name}clean

    #模拟器build

    xcodebuild -target${target_Name}-configuration Release -sdk iphonesimulator

    #真机build

    xcodebuild -target${target_Name}-configuration Release -sdk iphoneos

    #复制头文件到目标文件夹

    cp -R"${DEVICE_DIR_INCLUDE}""${INSTALL_DIR_Headers}"

    #合成模拟器和真机.a包

    lipo -create"${DEVICE_DIR_A}""${SIMULATOR_DIR_A}"-output"${INSTALL_DIR_A}"

    #打开目标文件夹

    open"${INSTALL_DIR}"

    fi

    相关文章

      网友评论

      • Engandend:脚本没成功 、使用合并命令 合成的framework 在debug模式可以编译(真机和模拟器) 但是release版本 编译报错 怎么回事?
        Apple Mach-O Linker (ld) Error Group
        clang: error: linker command failed with exit code 1 (use -v to see invocation)
      • 一鸣:建议代码用橙色代码框来实现,不要用“引用”功能来代替。
        纪小衰:@一鸣 中间很多我用的是本地的截图,代码只支持markdown,markdown不支持本地图片。。。心塞塞。。。

      本文标题:iOS制作framework

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