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

.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创建,使用完成;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345