美文网首页iOSiOS相关iOS 进阶
IOS-静态库(.a、framewrok)、动态库(.tbd、f

IOS-静态库(.a、framewrok)、动态库(.tbd、f

作者: 树下敲代码的超人 | 来源:发表于2017-09-27 17:11 被阅读380次

    技 术 文 章 / 超 人


    关于库思维导图:

    image.png

    静态库的文件列表如下,在 products 文件夹内的就是要生成的静态库。此刻是红色的,等到静态库编译成功就会变成黑色。


    image.png

    创建后的文件列表如下,可以看到只有一个 framework.h
    头文件。通过注释,我们可以理解,这个头文件是所有 public 头文件的集合:


    image.png

    bundle 一般和库命名相同。需要注意的是, bundle 并不会被打包进库中的,而是添加要单独添加到工程中,和 framework 相独立的两部分。向 bundle 中直接添加图片:


    9109394.png
    • 修改Build OptionsEnable BitcodeNO
    image.png
    • 修改signingCode signing identityDon't Code Sign (在提交苹果审核时,bundle如果有任何签名都会被拒)
    image.png
    • 修改User-DefinedCOMBINE_HIDPI_IMAGES为NO(iOS 创建Bundle时放入的图片资源(.png)在默认配置下会被转为.tiff格式,使用的时候找不到。因为在iOS中创建bundle时会用一个“hack”,为了使所有的运行需要更改一个配置。)
    image.png

    -在静态库中的Build PhasesTarget Dependencies添加Bundle。这样以后编译静态库时,bundle会自动编译。无需单独再编译

    Target Dependencies Target依赖,某些Target可能依赖某个Target输出的值,这里设置依赖
    Copy Bundle Resources 是指生成的product的.app内将包含哪些资源文件
    Compile Sources 是指将有哪些源代码被编译
    Link Binary With Libraries 是指编译过程中会引用哪些库文件

    image.png

    cocoapods打包库

    好了,终于到最后一部分了。前面已经介绍了手动创建库的方式,那么如何自动创建一个库?另外一点,前面提到过,在动态库内引入静态库,会和项目本身由 cocoapods 引入的库同名冲突,如何消除这一冲突?以上问题都可以通过 cocoapods 打包库实现

    创建工程
    只需要输入 pod 的 lib
    命令即可完成初始项目的搭建:

    pod lib create StaticWithCocoapods
    

    输出指令后,会提示确认五个问题,按需求回答即可:


    稍等片刻,就会自动生成一个工程。
    配置信息
    在项目目录下有一个 xxx.podspec
    配置文件,需要进行修改,摘录如下:

    Pod::Spec.new do |s|  
    s.name             = 'StaticWithCocoapods'
    
    s.version          = '0.1.0'  
    
    s.summary          = 'A short description of StaticWithCocoapods.'
    
    # This description is used to generate tags and improve search results.
    #   * Think: What does it do? Why did you write it? What is the focus?#   * Try to keep it short, snappy and to the point.
    #   * Write the description between the DESC delimiters below.
    #   * Finally, don't worry about the indent, CocoaPods strips it!  
    
    s.description      = <<-DESCTODO: Add long description of the pod here.                       DESC  
    
    s.homepage         = 'https://github.com/zhang759740844'
      
    s.license          = { :type => 'MIT', :file => 'LICENSE' }  
    
    s.author           = { 'Zachary' => '759740844@qq.com' }  
    
    s.source           = { :git => '/Users/zachary/Desktop/StaticWithCocoapods', :tag => s.version.to_s }  
    
    s.ios.deployment_target = '8.0'  
    
    s.source_files = 'StaticWithCocoapods/Classes/**/*' 
    
    s.resource_bundles = {    'StaticWithCocoapods' => ['StaticWithCocoapods/Assets/*.png']  }  
    
    s.public_header_files = 'StaticWithCocoapods/Classes/**/*.h' 
    
    s.frameworks = 'UIKit', 'MapKit'  s.dependency 'AFNetworking', '~> 2.3'  
    
    s.denpendency 'SVProgressHUD'end
    
    

    s.version 表示的是当前类库的版本号
    s.source 表示当前类库源
    s.sources_files 表示类库的源文件存放目录
    s.resource_bundles 表示资源文件存放目录
    s.frameworks 表示类库依赖的framework
    s.dependency 表示依赖的第三方类库

    其中要说明的是:

    • source 可以填写远端 git 仓库,也可以是像我写的那样的本地 git 仓库。
    • 依赖项不仅要包含你自己类库的依赖,还要包括所有第三方类库的依赖,只有这样当你的类库打包成 .a 或 .framework 时才能让其他项目正常使用。
    • source_file 路径中出现的通配符 *表示匹配任意字符, **表示匹配所有当前文件夹和子文件夹。
    • source_bundles 中花括号内的 'StaticWithCocoapods'
      就表示一个 StaticWithCocoapods
      bundle。

    添加文件
    sources_filespublic_header_files 以及 resource_bundle 中添加图片和类文件。在 demo 的文件夹下执行 pod install
    。现在打开 demo 工程,可以看到创建的 StaticWithCocoapods
    库的文件结构如下图:

    到这里一切正常,也可以使用 SVProgressHUD
    ,但是当我想用 [UIImage imageNamed:[[[NSBundle mainBundle] pathForResource:@"StaticWithCocoapods" ofType:@"bundle"] stringByAppendingString:@"/author.png"]];
    加载图片资源文件时,一直返回 nil

    好吧。虽然网上cocoapods打包教程不少,但是真正试过添加图片的人应该不多,最后在 Stackoverflow 的一个评论里总算找到了解决方法[Cocoapods]:Resource Bundle not accessbile

    原先 demo 中 profile 的内容如下:

    use_frameworks
    
    !target 'StaticWithCocoapods_Example' do
      pod 'StaticW', :path => '../'  
    
    target 'StaticWithCocoapods_Tests' do    
    inherit! :search_paths    
    pod 'FBSnapshotTestCase'  
    end
    
    end
    

    现在要删除 use_frameworks!
    以及其相关内容,变成这样:

    target 'StaticWithCocoapods_Example' do  
    pod 'StaticWithCocoapods', :path => ‘../‘
    end
    

    再次尝试加载图片,可以得到正确结果. _


    提交代码

    • 使用 sourcetree 添加本地仓库
    • 提交上面的所有改动
    • 为改动添加 tag 为 0.1.0

    设置好后如图:


    这里要注意,tag 一定要打上,版本控制的时候就是以 tag 来辨别的。


    验证类库
    开发完成静态类库之后,需要运行pod lib lint验证一下类库是否符合pod的要求。添加 --allow-warnings
    忽略警告:


    打包库

    打包库需要一个 cocoapods 的插件 cocoapods-packager来完成类库的打包。
    在终端执行以下命令,安装插件:

    sudo gem install cocoapods-packager
    

    在目标文件夹内执行以下命令,完成打包:

    pod package StaticWithCocoapods.podspec --force
    

    打包成 .framework,也可以用--library打包成 .a。不过 cocoapods 之前有过打包成 .a但是没有暴露出头文件的bug,懒得试有没有修复了,所以还是都打成 .framework
    吧。

    现在在目标文件夹下就会多出一个 StaticWithCocoapods-0.2.0
    目录,里面是打包好的 framework 。至于如何将打包好的库添加到 cocoapods的官方库内,这个就没有研究了,因为,在很长的一段时间内我都不会用到。有兴趣的可以看看 cocoapods 的官方文档,自行研究下。

    相关文章

      网友评论

      • CTChan:好
      • CTChan:非常
      • 颠倒的结尾:你好,请教一个问题。最后你说的用cocoapods打包库,最终是把打包好的framework给其他项目用吗?假如说这个库包含了afnetworking,而使用这个库的项目没有导入afnetworking,是不是需要自己导入?如果使用这个库的项目本身就导入了afnetworking,会冲突吗?
        树下敲代码的超人:如果你的framework是动态库就不会冲突,但是导入两份一样的afnetworking会造成体积变大哦。如果你的fremework是静态库就会冲突,建议你的静态库给别人使用时只导入afnetworking的所有.h文件,并把afnetworking的.h放在静态库的Headers的public里公用出去,而外部在使用你的静态库时必须导入afnetworking .h和.m的所有文件在自己的项目里。这样你的静态库中会直接调用外部的afnetworking的实现。

      本文标题:IOS-静态库(.a、framewrok)、动态库(.tbd、f

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