重庆分公司,新征程启航

为企业提供网站建设、域名注册、服务器等服务

ios开发.a文件,ios文件我的iPhone

iOS 创建自己的SDK静态库(.a文件)并使用cocopods集成

iOS开发中支持静态库与动态库,不过使用动态库,上架会有麻烦。这里讲到如果创建静态库.a文件,其实很早之前公司要求做wifi的SDK的时候就开始涉及这个东西了,但一直没写出来。

创新互联建站长期为上千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为万秀企业提供专业的做网站、成都网站设计万秀网站改版等技术服务。拥有10多年丰富建站经验和众多成功案例,为您定制开发。

首先新建一个静态库的项目

注意这里选择的不是模拟器运行,继续

这时候就得到了两个.a文件。

把Release-iphoneo和Debug-iphonesimulator复制到桌面新建的文件夹

最后使用命令lipo -create xxx.a xxx2.a -output xxx3.a

新建项目或者随便找个已创建测试项目,可直接拖进来放在Frameworks目录下

再把暴露的.h文件引进来

接下来,我把静态库和暴露的.h文件放入cocopods中使用,将静态库和暴露的.h上传至github上的仓库。并更新一个release版本。

更改cyhCheckphoneNum.podspec版本号,与spec.source_files和spec.vendored_libraries

更新github上的release版本

验证是否通过,通过上传至github

上传至cocopods

最后使用cocopods安装使用

iOS集成三方库时出现.a和.o文件重复定义问题处理

我们在项目中引入第三方库的时候,容易出现类似这样的问题:.a文件中XXX.o重复定义 

duplicate symbol _OBJC_CLASS_$_WapAuthHandler in:

/Users/XXXname/Library/Developer/Xcode/DerivedData/XXObjext-gcnzomsbbunnlyfihyndulghsulr/Build/Products/Debug-iphonesimulator/libXXX.a(WapAuthHandler.o)

/Applications/Xcode.app/Contents/Developer/Library/Frameworks/XXX.framework/XXX(WapAuthHandler.o)

ld: 2 duplicate symbols for architecture i386

clang: error: linker command failed with exit code 1 (use -v to see invocation)

我们的解决办法是将其中一个.a文件中的.o删除掉来解决问题,下面是方解决方法

准备工作:

将其中一个点.a复制拷贝出来到一个新文件夹,再将.a命名为libx.a,在终端中cd到.a文件所属文件夹下,输入命令来查看包(.a)信息:lipo -info libx.a

如果提示fat file,如下

Architectures in the fat file: libx.a are: i386 armv7 x86_64 arm64

那 么代表这个包是支持多平台的,如i386 armv7 x86_64 arm64。这需要我们逐一做解包重打包操作,否则我们只需要做一次【1-6】操作即可。

1、  创建临时文件夹,用于存放armv7平台解压后的.o文件:mkdir armv7

2、  从.a中取出armv7平台的包并存放在armv7文件夹中: lipo libx.a -thin armv7 -output armv7/libx-armv7.a

3、  查看armv7平台的包中所包含的文件列表:ar -t armv7/libx-armv7.a

4、  从armv7平台的包中解压出object file(即.o后缀文件):cd armv7 ar xv libx-armv7.a

5、  找到冲突的包( WapAuthHandler ),删除掉rm WapAuthHandler.o

6、  重新打包object file(armv7平台包):cd .. ar rcs libx-armv7.a armv7/*.o ,可以再次使用【2】中命令确认是否已成功将文件去除

7、  将其他几个平台(armv7s,i386,x86_64,arm64)包逐一做上述【1-6】的操作

8、  重新合并为fat file的.a文件(去掉重复.o的):lipo -create libx-armv7.a libx-armv7s.a libx-i386.a -output libMiPushSDK-new.a

9、  拷贝到项目中覆盖原来的.a文件就OK了。

iOS 之.a静态库创建、打包以及静态库之间的引用

实际开发中离不开静态库的使用,记录一下

.a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。

.a文件不能直接使用,至少要有.h文件配合,.framework文件可以直接使用。

.a + .h + sourceFile = .framework。

创建

配置如下

加到主工程

配置路径

导入头文件 使用

targets-Build Phases-Copy Files-"+"你需要公开的头文件

所有流程都跟上面的一样,只是我们运行打包时要选择真机运行,你可以选择自己插上去的真机,也可以选择Generic ios Devices。当然不要忘记了设置支持所有真机机型架构: Build Active Architecture Only 设为NO。

分别使用真机或者Generic iOS Device 和 随便一个模拟器运行静态库 得到模拟器静态库和真机静态库 然后在Finder 中打开

Show in Finder

通过命令行合并 (注意 库的名称要一致)

lipo -create 第一个.a文件的绝对路径 第二个.a文件的绝对路径 -output 最终的.a文件路径

然后在工程中将这个.a 替换就支持真机和模拟器了

workspace里 Argos是主工程 LJNetwork是一个静态库工程 AGFramework.framework是打包好并导入到主工程的静态库

现在LJNetwork要引用AGFramework.framework库

只需要在LJNetwork的Build Setting — User Header Search Paths 中 拉入AGFramework.framework中的Headers文件夹的路径

静态库LJNetwork引用 静态库LJFoundation的文件

配置如下

静态库LJNetwork要引用pods中的AFNetworking 如下设置

个人博客地址:

iOS SDK开发中的情形

iOS SDK开发就是为某一个应用场景、或领域、或需求,提供一个已实现的、封装好的、可供直接使用的模块。

其主要由两部分组成:用来为类型或常量声明的头文件列表、具体实现的二进制文件。

所以SDK开发中的主要问题点集中在:

1. 头文件是否能被使用的工程索引到

2. 二进制文件是否能被使用的工程搜索到

本篇文章不写制作SDK的具体步骤,仅仅讨论制作SDK时的一些情形。

SDK开发中关于头文件设置:

凡是提供给外界使用的类、结构体、枚举、常量等,定义它们的头文件必须要在工程的Build Phases-Headers-public下面。并且这些头文件都需要包含在与SDK工程同名的头文件中(这条不是必须,只是这么做会显得更加规范。别人使用SDK的时候,只需要引入SDK同名的头文件即可)

设置库文件生成动态的还是静态的:

Project Name-Target Name-Build Settings-搜索框搜“Mach”-修改“Mach-O Type”为动态或静态,则相应可生成动态或静态的库文件。

先解释说明以下图片中出现的工程名字:

SDKDemo :制作的向外提供的SDK库文件(与SDK工程名同名)

SDKApp :引用SDK库文件(本文指的是SDKDemo)的App工程

SDKStatic :新建工程时,选择iOS-Framework Library-Cocoa Touch Static Library. 用来生成.a文件的工程

SDKFramework :  是个Framework库文件(可能是动态的,也可能是静态的),用于模拟被SDK依赖的.framework文件

下面分几种情况来讨论SDK开发的注意事项:

1. 生成动态SDK库文件。

创建工程的时候,根据默认配置编译是生成动态库的。

App工程中引入动态库的时候,需要在

App工程:Project Name-Target Name-General-Embedded Binaries下添加引入的动态库。否则运行时会报如下类型错误:

嵌入动态库编译后,生成的App文件中会多一个Frameworks目录(可右键.App文件查看包内容),里面全是Embedded Binaries下添加的动态库

2. 打包为静态库

SDK工程:Project Name-Target Name-Build Settings-搜索框搜“Mach”-修改“Mach-O Type”为静态库

App工程引入静态库很简单,直接引入就行,不需要额外配置:

tips:

合并真机与模拟器版本时的命令格式为:

lipo -create 模拟器版本的路径 真机版本的路径 -output 合并后的版本存放路径

1. 合并时lipo -create接收的模拟器版本和真机版本两个参数的前后顺序没有关系,合并后的版本通过命令查看架构信息显示结果是完全一致的。模拟器架构信息显示在前,真机架构信息在后。

2. 合并后的版本无论替换真机版本的Framework中的目标文件还是模拟器版本的Framework中的目标文件,App工程中引入被替换的Framework后在真机和模拟器上都能跑起来

首先创建SDKStatic工程,生成一个.a文件。

该工程只是简单继承了UIButton,并重写了initWithFrame方法。为每一个MyButton对象默认生成标题和背景色:

生成的.a文件如下,可以看到里面包含了MyButton.o文件:

在SDK工程中引入.a文件。下面分两种情况来看生成的SDK库文件:

1. SDK库文件做成动态库(设置方法看开头部分)

.a文件内容被整合进了SDK动态库文件中,引入App工程中时,只需要引入SDK动态库就可以了

2. SDK库文件做成静态库(设置方法看开头部分)

包中的信息:

.a文件内容同样被整合进了SDK静态库文件中,这个更好理解。引入App工程中时,只需要引入SDK静态库就可以了

总结下:

制作SDK库时,如果有依赖的.a文件,则最终生成的SDK库文件会合并.a文件的内容,而不论SDK库文件是动态还是静态的。

下面的SDKFramework是个Framework库文件(可能是动态的,也可能是静态的)

SDKFramework工程添加的内容和SDKStatic工程是一样的。也是自定义MyButton,默认生成标题和背景色(拷贝文件到工程):

SDKDemo工程自定义了MyView,默认生成的MyView对象添加了一个MyButton按钮和背景色:

1. 如果.framework文件是动态库

a. SDK打包为静态库,如下:

静态SDK包和动态SDKFramework.framework文件是彼此独立的。引入静态SDK包时,必须也导入SDKFramework.framework,否则编译不过,因为静态包有引入动态库中的符号。

b. SDK打包为动态库,如下:

两者还是彼此独立的。动态SDK包中会记录依赖的动态.framework rpath,App运行时,dyld会根据这个信息去加载对应的.framework依赖文件。如果找不到App将会在启动时奔溃...

2. 如果.framework文件是静态库

a. 首先SDK打包为动态库看看:

经实践,依赖的静态库会被整合进动态SDK包自身中。App中引入时,只需要导入SDK包就可以。我们在SDKApp中导入SDKDemo,运行可以看到如下效果:

b. 再看看SDK打包为静态库:

根据上面截图中信息,App中导入SDK包时,也必须导入依赖的.framework了。否则编译时将会出现如下图所示找不到符号的错误:

追加导入依赖的.framework,再次编译运行。OK!!!

总结:

1. 依赖的.framework为动态库

制作的SDK库文件不论动态还是静态的。和依赖的.framework文件本身是彼此独立的,不会发生符号整合的现象

2. 依赖的.framework为静态库

如果制作的SDK库文件是动态的,则依赖的.framework静态库内容会被整合进SDK库文件中

如果制作的SDK库文件是静态的,则彼此是独立的

这里又得分几种情况讨论:

1. Podfile中不使用use_frameworks!  pods库生成的是.a文件

a. 如果SDK制作成静态库:

  SDK静态库不会整合Pods里三方库中的符号,最终导入App工程时,需要SDK静态库、Pods中的三方库文件一起导入

b. 如果SDK制作成动态库:

  Pods库中的符号会被合并整合进入SDK库中,导入工程时,只需要导入SDK包就OK了

2. Podfile中使用use_frameworks!  pods库生成的是.framework文件。其中Pods_工程名.framework文件是个静态库,管理的第三方库生成的是framework动态库

a.如果SDK制作成动态库:

SDK中会包含引入三方库的rpath,App中引入SDK包时,也必须引入三方库,否则dyld加载不了指定库导致App启动时奔溃

b. 如果SDK制作成静态库:

静态SDK中会忽略Pods中的库中定义的符号(也即彼此是独立的)。如果静态SDK中引用了动态pods库中定义的符号,只要在App工程中也导入pods中动态库,并在embeded binaries中添加。一样是可以编译运行的。

其实怎么编译,SDK工程中是个什么情形都不重要。重要的是要明白库文件的本质,及它是如何发挥作用的?在什么阶段发挥作用?然后学会查看编译运行时的报错信息,并配合使用otool、nm、lipo、ar、file等这些命令去查看库文件的一些信息,最终追踪定位到问题。

原谅我最后都没怎么贴图了,因为流程都和前面差不多。我也写的手累了。如果你还有什么疑惑可以在下面评论,我会尽量及时回复。

iOS中如何查看.a文件中包含的所有.o文件

1. 需要静态库

2. 取出arm64架构(要求.a必须是NOFat,这里示例是去arm64架构)

3. 使用Linux ar命令

ar -v -t 文件路径 (表示:显示库的目录)

4. 效果如图

参考链接:   

IOS SDK开发详解(.framework、.a、Bundle资源文件创建、SDK中使用其他SDK等)

软件开发工具包(缩写:SDK,英语全称:Software Development Kit),一般都是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。

在OC的开发中,我们涉及到的一般是静态库(.a)或者动态库(.framework)。(注:不是所有的.framework就一定是动态库)

.a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。 .a文件不能直接使用,至少要有.h文件配合(微信的SDK就是这种形式),.framework文件可以直接使用。 .a + .h + sourceFile = .framework。 建议用.framework。再者 静态方式开发,一直是iOS SDK开发的主流方式。

终端输出为:armv7 arm64 是真机架构;i386 x86_64 是模拟器架构。

终端输出为:arm64 是真机架构;x86_64 是模拟器架构。

Bundle 和 其他的SDK都要和创建的SDK放在同一个文件夹,然后拖入要使用的项目中,如果该项目中的SDK和创建的SDK中的引用的SDK重复,那么就只要保持存在一个就好了。


网站栏目:ios开发.a文件,ios文件我的iPhone
当前链接:http://cqcxhl.com/article/pheded.html

其他资讯

在线咨询
服务热线
服务热线:028-86922220
TOP