美文网首页
.a /.framework /.bundle 理解与使用

.a /.framework /.bundle 理解与使用

作者: IThai | 来源:发表于2017-12-14 16:17 被阅读0次

.a /.framework /.bundle 理解与使用

前言: 为了防止世界被破坏,为了维护宇宙的和平,遂决定写下此文;

本文不对库文件(包括静态库,动态库).framework 及 .bundle 概念原理进行介绍,可自行查找资料;主要介绍如何创建静态库.a 资源集合.framework,资源包.bundle的创建使用;

.framework打包,并使用集合包agg集成的示例demo:示例demo

一:什么是静态库.a ,什么是资源集合.framework

(1.) .a 二进制库静态库文件;

(2.).a + .h + sourceFile = .framework。

.framework 资源集合;

二:使用背景

为什么使用.a ,.framework?

在某些情况下,我们或者其他开发者不想看到代码的实现,只需要调用我们的某个功能模块,这个时候,.a,.framework 就可以很好的解决类似的问题;

友情提示:你在创建静态库的时候一定遇到过一些错误,而在这些错误中常常会看到如下怪物:i386 ,x86_64,armv6,armv7,armv7s,arm64 (http://blog.csdn.net/lizhongfu2013/article/details/42387311);这些是什么,可以去查看iOS cup架构的资料,相信你一定会感激我的。注意区分真机和模拟器的区别。好的东西一定是从别人那里看,然后自己体会到的,别怪我不写明白,相信你一定会感激我的。

三:.a创建

打包静态库,如下图:

(1.)打开xcode ,快捷键command+shift + N 创建新工程:

选择static library 静态库,next

(2.)设置静态库名字为你需要的名字:

此时有.h .m俩文件:

(3.)将.m文件删除,拖入你写好的功能代码(.h ,.m ),或者,直接在当前.h .m中写入测试代码:

(4.)公开头文件

将你要公开的头文件,添加到targets->Build Phases->Copy Files->"+下,如图staticLibDemo.h默认已添加

(5.)最后在打包前要进行两项处理:


                                            第一项:支持所有设备 

模拟器 :(选中需要支持的模拟器设备)在targets->Build settings->Bulid Active Architecture Only-> 设置为 “NO” ,编译

真机:(选中Generic IOS Deview)在targets->Build settings->Bulid Active Architecture Only-> 设置为 “NO”,编译

编译之后会看到 静态库文件由红色变为黑色:

可以选中.a文件进入查看,包含include 和.a文件,如下图:


将支持不同arm处理器的.a合成一个通用.a(arm64 arm64e armv7 armv7s i386 x86_64这些指令集的处理器)

以命令 lipo -create 你刚生成的.a文件名称(vXXXX_64.a vXXXX_V7.a XXXX_V7s.a) -output XXXX_all.a 合成他们成为新的.a文件。

备注:如果需要真机模拟器64 32为都支持,可以分别选择当前版本最高模拟器和最高真机分别生成各自.a,然后将这两份.a合成一份。(我分别是在iphone 11 pro max 和 真机x max下生成的。然后测试了模拟器 6s,ipad mini 4,iphone 11 都没问题。真机测试了x max和iphone 6。我当前mac系统为:macOS mojave 10.14.6 ,xcode版本为11.1)

       第二项:禁掉一些无用项,提高编译效率

在targets->Build settings下:

* Dead Code Stripping设置为NO

* Strip Debug Symbol During Copy 全部设置为NO

* Strip Style设置为Non-Global Symbols

注:当然第二项的设置不做也可以。

四:.a的使用

将刚刚创建好的.a文件和 StaticLibDemo.h 导入到你要加入这个静态库文件的项目中,然后在你的项目中调用即可,如图:

StaticTestDemo是我刚新建的项目,将你打包好的静态库文件.a和.h导入

然后在你的项目要使用静态库的地方,导入头文件,调用方法,如图:

可以看到,静态库中方法调用成功。

至此,.a创建,使用完成;

五:.framework创建

(1.)创建,如图

(2.)创建完成后的样子:

(3.)将功能模块拖入,如图

(4.)公开头文件:将project下要公开的头文件,拖入到public下;并在.framework的.h中导入公开的头文件,如图:

(5.)设置为静态库,如图:target->BuildSetting ->Linking->Mach O Type “Static Library”

(6.)


                                            设置支持所有设备 

模拟器 :(选中任意模拟器设备)在targets->Build settings->Bulid Active Architecture Only-> 设置为 “NO” ,编译

真机:(选中Generic IOS Deview)在targets->Build settings->Bulid Active Architecture Only-> 设置为 “NO”,编译

设置完成,编译运行,.framework由红变黑,成功;

(7.)使用:新建一个项目,将.framework导入到项目中,并在要使用的地方导入头文件,如图:

至此,.framework创建,使用完成;

六:.bundle创建,使用

(1.)创建:

在桌面创建一个空文件夹,在文件夹中放入要导入的资源文件,如图片等,

修改后缀为.bundle,如图:

选择添加

创建完成

(2.)将bundle包拖入项目中即可使用

七:多加入些知识吧:Aggregate

(1.)Aggregate是什么?是一个集合,就好比sdk。刚才你创建.a静态库文件和.framework的时候,有提到过,要创建模拟器和真机两种,而此处的Aggregate就是为了将两者都包含在一起,方便两种情况都可以使用的。(当然合并你制作的模拟器.framework和真机.framework的方法还有一种,使用命令的方法,此处不再赘述,可搜索.framework合并 。我习惯使用第一种方法。为什么?为了防止世界被破坏啊。)

(2.)好,马上来说下Aggregate如何创建:

(a.)在已经进行了模拟器和真机编译成功的.a 或者.framework中,Show in Finder 查看项目下文件内容,如图:(等下aggregate创建成功后对比)

(b.)创建aggregate,在targets下点击添加按钮“+”如图:

和之前找aggregate有区别,在Cross-platfrom下找到aggregate如图:

agg命名最好和你的库名一致如图:

现在,你的3个圈将创建完成了,接下来进行脚本配置:

(c.)新建一个脚本,如图:


                             - — - — - - — .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

                - - — - — —将上边脚本复制到你刚新建的脚本中 — — - — - — -


                       - - — - — - - — .framework的脚本如下 — - - — — - - — - 


                    - - — - - — —将下边脚本复制到你刚新建的脚本中: — — - - — — - 

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

             - --------— —将上边脚本复制到你刚新建的脚本中 — — - — - — 


如图:

运行如图:

最后,进入项目文件夹下,与第一步图对比:

发现此时得到我们需要的.framework。



最后,由于上边图片太多,在结尾温馨回顾下吧:

1. .a 静态库的创建使用:

(a.)打开xcode ,快捷键command+shift + N 创建新工程:选择static library 静态库,next

(b.)  设置静态库名字为你需要的名字:

(c.)  将.m文件删除,拖入你写好的功能代码(.h ,.m ),或者,直接在当前.h .m中写入测试代码:

(d.)  公开头文件:  将你要公开的头文件,添加到targets->Build Phases->Copy Files->"+下,如图staticLibDemo.h默认已添加

(e.)  最后在打包前要进行两项处理:


         —-----— — - - 第一项:支持所有设备 - - - — — - — - — —

模拟器 :(选中任意模拟器设备)在targets->Build settings->Bulid Active Architecture Only-> 设置为 “NO” ,编译

真机:(选中Generic IOS Deview)在targets->Build settings->Bulid Active Architecture Only-> 设置为 “NO”,编译

编译之后会看到 静态库文件由红色变为黑色

可以选中.a文件进入查看,包含include 和.a文件;


      - - — - — - - -第二项:禁掉一些无用项,提高编译效率 - — - --------— 

在targets->Build settings下:

* Dead Code Stripping设置为NO

* Strip Debug Symbol During Copy 全部设置为NO

* Strip Style设置为Non-Global Symbols

注:当然第二项的设置不做也可以。

(f.)  .a的使用

将刚刚创建好的.a文件和 StaticLibDemo.h 导入到你要加入这个静态库文件的项目中,然后在你的项目中掉用即可;

StaticTestDemo是我刚新建的项目,将你打包好的静态库文件.a和.h导入

然后在你的项目要使用静态库的地方,导入头文件,调用方法;

可以看到,静态库中方法调用成功。

至此,.a创建,使用完成;

2  .framework创建使用:

(a.)创建

(b.) 将功能模块拖入

(c.) 公开头文件:将project下要公开的头文件,拖入到public下;并在.framework的.h中导入公开的头文件;

(d.) 设置为静态库,如:target->BuildSetting ->Linking->Mach O Type “Static Library”


                    --— - —— — - -设置支持所有设备 - - - — — - — -

模拟器 :(选中任意模拟器设备)在targets->Build settings->Bulid Active Architecture Only-> 设置为 “NO” ,编译

真机:(选中Generic IOS Deview)在targets->Build settings->Bulid Active Architecture Only-> 设置为 “NO”,编译

设置完成,编译运行,.framework由红变黑,成功;

(e.) 使用:新建一个项目,将.framework导入到项目中,并在要使用的地方导入头文件;

至此,.framework创建,使用完成;

相关文章

网友评论

      本文标题:.a /.framework /.bundle 理解与使用

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