Mac终端的Cocoapods创建自己公有库

一,前言

  • 为什么要用Cocopods

      通常在开发的过程中,大多时候,我们会处理一类相同的操作,比如对于字符串String的邮箱验证,是否为空,手机号验证,或者一些UIView的动画操作,我们为了避免写一些重复的代码,可能经过类目或者延展的形式对原有的类进行了一个扩充。
      还有一些是工程中一些基本的公共组件,比如城市列表,刷新控件,网络请求库或者商品的目录这种基本公共组件,在工程中好多地方需要调用,我们都可以进行封装成一个组件功能模块。为了以后方便在其他App中使用,我们可以使用Cocoapods把这些小点子,小功能,可以封装成一个pod,当下次使用的时候,只需简单配置就可以了。
      这一点特别是在公司开发多个项目的时候,可以很方便快速的共享公共的代码,节约开发时间,这就是为什么好多公司喜欢组件化管理代码。至于库是创建私有的还是公共的,看自己和公司要求而定,大多情况下公司的是私有库pod。当然通过cocopods除了集成自己开发的功能模块外,还可以引用第三方发布到cocopods上的功能功能模块,比如友盟的分享,神策的统计等等好的功能模块。总之Cocopods 减少了代码的耦合性,提供了开发效率等等。

  • 理解Cocopods原理

    • cocoapods的下载原理

      举例: s.source = { :git => 'git@gitlab.xxx.net:ios-thirdpartservice/xxxreact.git', :tag => '1.0.0' } //s.source 位于.podspec内

      当使用Cocoapods导入私有库时,Cocoapods先是根据:git => ‘git@gitlab.xxx.net:ios-thirdpartservice/xxxreact.git’找到对应的git仓库,然后根据:tag => ‘1.0.0’定位到对应tag的提交(如果没有注明Pod依赖库版本则定位到最后一次的提交),然后在这次提交中检索后缀为.podspec的文件(文件可以随便命名)。找到podspec文件后先要验证s.name是否与Podfile中的一致,如果不一致则install时会报错:[!]Unable to find a specification for ‘React’. 如果验证成功后,就会根据Podspec中的s.source_files找到需要导入的代码文件,并通过其他的的数据找到对应的配置文件或资源文件等。最后,将其下载到本地项目中。

      当使用Cocopods导入共有库时,和以上原理也相同。只是共有库要将podspec文件上传到cocoapods。在导入的时候通过名字Reactcocoapods匹配对应的podspec,然后根据s.source去找到对应的仓库和对应的版本,然后会再去匹配新的podspec,后边的步骤就完全相同了。

    • 集成原理

      当所有的依赖库都下载完后,Cocoapods会将所有的依赖库都放到另一个名为Pods的项目中,然后让主项目依赖Pods项目。这样,源码管理工作都从主目录移到了Pods项目中。Pods项目最终会编译成为一个名为libPods.a的文件,主项目只要依赖这个.a文件即可。对于资源文件,Cocoapods提供了一个名为Pods-resource.shbash脚本,该脚本在每次项目编译的时候都会执行,将Pods依赖库的各种资源文件复制到目标目录中。Cocoapods还通过一个名为Pods.xcconfig的文件来在编译时设置所有的依赖参数

      • libPods.a

      • Pods-resources.sh

      • Pods.xcconfig

    • 版本控制原理

      当执行完pod install之后,cocoapods会生成一个podfile.lock的文件。podfile.lock文件最大的用处在于多人开发。如果你没有在podfile中指定pods版本pod ‘React’,那么默认为获取当前React依赖库的最新版本。当团队中的某个人执行完pod install命令后,生产的podfile.lock文件就记录下了当时最新pods依赖库的版本,这时团队中的其他人check下来这份包含podfile.lock文件的工程以后,再去执行pod install命令时,获取下来的pods依赖库的版本和最开始用户获取到的版本一致。如果没有podfile.lock文件,后续所有用户执行pod install命令都会获取最新版本的React,这就可能造成一个团队使用的依赖库版本不一致,这对团队协作来说绝对是个灾难。在这种情况下,如果团队想使用当前最新版本的React依赖库,
      有两种方案:
      1、更改podfile,使其指向最新版本的React依赖库
      2、执行pod update命令;鉴于podfile.lock文件对团队协作如此重要,所以应该加入到版本控制里面。

    • 区分pod install 与 pod update

      我们在使用这个工具时,最经常用到的命令就是pod installpod update;这两个命令都能为我们安装指定的Pod库,但是他们的使用是有区别的,有各自不同的作用和适用场景;了解这两个命令的差异前,需要先对Podfile.lock文件有所了解;Podfile.lock文件中记录了每个pod的当前已安装版本,并锁定这些版本(.lock命名因此而来);当运行pod install命令时,它只解析尚未列在Podfile.lock中的依赖库,在下载并安装新的pod时, 会在Podfile.lock文件中写入新的pod库的当前指定版本;对于已经在Podfile.lock中列出的pod, pod install命令不会尝试检查是否有更新的版本;而是直接使用在Podfile.lock文件中的pod版本;

      • pod install

        在项目中第一次使用CocoaPods时,安装指定的pod库需要使用这个命令;当在Podfile中 增加 或 删除 某个pod后, 使用这个命令进行更新;pod install不会尝试更新已安装的pod的版本;

      • pod update

        1、当运行pod update时,CocoaPods会把Podfile中所有的pod都更新到最新版本;并在Podfile.lock中写入最新的版本号;
        2、执行pod update PODNAME命令更新指定的某个PODNAME库到最新版本;

      • pod outdated

        pod outdated命令可以检测出所有比Podfile.lock中写入的版本(每个pod当前安装的版本)更新的pod版本;

  • 了解Cocopods的本地目录

    我们先来看看CocoaPods本地目录中有什么

    • $ cd ~/.cocoapods/repos/master 或者显示隐藏文件

    • $ defaults write com.apple.finder AppleShowAllFiles -boolean true ; 

      然后进入 ~/.cocoapods/repos/master

      你会发现 master 是一个 git 仓库,输出仓库的远程地址,发现是一个GitHub仓库

    • $ git remote -v

      origin https://github.com/CocoaPods/Specs.git (fetch)
      origin https://github.com/CocoaPods/Specs.git (push)

      继续,我们进入Specs文件夹一直往里点,你会发现很多框架以及版本号

    • $ pod search YYImage

      选择一个框架,通过pod搜索 Specs 文件夹中的框架,输出框架信息
      -> YYImage (1.0.4)
      Image framework for iOS to display/encode/decode animated WebP, APNG, GIF,
      and more.
      pod 'YYImage', '~> 1.0.4'
      - Homepage: https://github.com/ibireme/YYImage
      - Source: https://github.com/ibireme/YYImage.git
      - Versions: 1.0.4, 1.0.3, 1.0.2, 1.0.1, 1.0, 0.9.5, 0.9.4, 0.9.3, 0.9.2,
      0.9.1, 0.9.0, 0.8.9 [master repo]
      - Subspecs:
      - YYImage/Core (1.0.4)
      - YYImage/WebP (1.0.4)

      每个版本号对应的一个json文件,描述了每个对应版本的框架的信息、配置、及源码下载地。

      我们在 CocoaPods 发布我们的框架时,就是要在 master 仓库中添加我们的仓库描述信息,然后push到远程仓库中。不过这个过程不用我们手动去操作,只需要通过pod命令进行操作即可。

二,iOS 创建自己的Cocoapods公有库及私有库  

  • 需要做的工作包括以下几点

    • 创建一个本地的仓库,将自己的代码搞进去

    • 将自己的代码上传到远程私有仓库中去

    • 创建一个pods 的描述文件 .podspec

    • 修改.podspec描述文件中的相关的描述信息

    • 创建远程内部私有Spec Repo仓库

    • 向私有的Spec Repo仓库中提交.podspec

    • 在个人项目中的Podfile中增加刚刚制作的好的Pod并使用

    • 后期的升级维护

  • 具体详细的步骤如下

    • 创建远程仓库注意点

      • 正规的仓库都有一个license文件,Pods依赖库对这个文件要求比较严格,需要有这个文件,建议使用MIT类型的license

      • 代码版本要打tag(要在代码版本上传以后打tag)

      • pod 支持 .a静态库.framework 以及文件,不一定要是可运行的工程里面的某个组件

      • 放代码的仓库不一定非要是Git仓库,只要是可以获取到相关代码文件就可以,可以是SVN的,也可以是zip包,区别就是在podspec中的source项填写的内容不同

    • 创建一个pods 的描述文件 .podspec
      • 如果你已经有先有工程可以使用如下命令直接创建.podspec文件

        $ pod spec create MyViewExtension<这个名称一般和创建的项目名称一样就可以>
      • 或者使用如下命令创建完整项目工程目录

        $ pod lib create MyViewExtension <这个名称一般和创建的项目名称一样就可以>

        使用这个命令会询问如下问题,根据项目情况选择即可

    • 修改.podspec描述文件中的相关的描述信息

      详情可参考CocoaPods的官网的PodSpec语法

      Pod::Spec.new do |s|
      # 项目的名称
      s.name = "MyViewExtension"
      # 项目的版本号,通过项目git的tag标签进行对应,这里的标签代表的版本
      s.version = "0.0.1"
      # 项目简单的描述信息
      s.summary = "Just Testing."
      # 项目的详细描述信息,注意,这里的文字的长度,一定要比上面的s.summary长,不然会认为格式不合格
      s.description = <<-DESC
      this project provide all kind of KeychainDeviceID for iOS developer
      DESC
      # 项目的网页主页信息,这里可以直接写自己的远程仓库的主页的地址
      s.homepage = "https://github.com/RunOfTheSnail/MyViewExtension"
      # 开源协议
      s.license = "MIT"
      # 作者信息
      s.author = { "zhangyan" => "17***24@163.com" }
      # 这个比较重要,指的就是git的对应的远程仓库的地址以及版本号,版本号直接获取的是上面的s.version
      # 项目地址,这里不支持ssh的地址,验证不通过,只支持HTTP和HTTPS,最好使用HTTPS
      # Supported Keys:
      # :git => :tag, :branch, :commit, :submodules
      # :svn => :folder, :tag, :revision
      # :hg => :revision
      # :http => :flatten, :type, :sha256, :sha1
      s.source = { :git => "https://github.com/RunOfTheSnail/MyViewExtension.git", :tag => s.version }
      # 支持的平台及版本
      s.platform = :ios, "11.0"
      # 支持的ios最低版本
      s.ios.deployment_target = "7.0"
      # 如果是 Swift 的话指定 Swift 编译版本
      # s.swift_version = "4.0"
      # 必备项,代码源文件地址,如果有多个目录下则用逗号分开,否则"public_header_files"等不可用
      s.source_files = "GSLXYKeychainDeviceID/KeychainDeviceID/**/*.{h,m}"
      # 公开头文件地址
      # s.public_header_files = "Pod/Classes/**/*.h"
      # 所需的系统framework,多个用逗号隔开,不需要后缀名
      # s.framework = "SomeFramework"
      s.frameworks = "UIKit", "AnotherFramework"
      # 需要弱链接的框架
      # s.weak_framework = "Twitter"
      # s.weak_frameworks = "Twitter", "SafariServices"
      #项目依赖的库文件(这个是系统的库文件),不需要后缀名,比如sqlite,libz等.以lib开头的需要省略掉lib这三个字母.例如:libz需要简写为z否则报错
      # s.library = "iconv"
      # s.libraries = "iconv", "xml2"
      # 第三方或自己创建的 .Framework的名称
      # s.vendored_frameworks = "YostarLib.framework"
      # 第三方或自己创建的 .a静态库的名称
      # s.vendored_libraries = "libYostarStaticLib.a"
      # 添加资源文件
      # s.resource = "XXX/XXXX/**/*.bundle"
      # s.resources = "XXX/XXXX/**/*.bundle"
      # CocoaPods会把这个库配置成static framework,同时支持Swift和Objective-C
      # s.static_framework = true
      # 依赖关系,该项目所依赖的其他,当在加载的时候也会一块把相关的依赖的库加载下来,如果有多个需要填写多个
      # s.dependency "JSONKit", "~> 1.4"
      # 是否使用ARC,如果指定具体文件,则具体的文件使用ARC
      s.requires_arc = true
      # 指定项目配置,如HEADER_SEARCH_PATHS、OTHER_LDFLAGS等
      # s.xcconfig = {"OTHER_LDFLAGS" => "-ObjC"}
      end
    • 修改完毕之后进行检验一下.podspec的格式有木有问题

      $ pod lib lint
      完整lint格式
      $ pod lib lint --allow-warnings --use-libraries --verbose --no-clean --sources='http://10.11.180.29/mobileDevelopers/YZT-Loan-Pod-Spec.git'
      --verbose:打印错误
      --allow-warnings:允许警告,默认有警告的podspec会验证失败
      --fail-fast:遇到错误马上停止,默认会完成全过程再停止
      --use-libraries:如果自己私有库包含library,引用了.a、.framework,在验证和提交时需要加
      --no-clean:检查问题
      --sources:如果依赖了其他不包含在官方specs里的pod,则用它来指明源,比如依赖了某个私有库。多个值以逗号分隔
    • 创建远程内部私有Spec Repo仓库

      创建远程内部私有Spec Repo仓库, 需要到Github或其他代码托管平台创建远程仓库, 之后将远程仓库克隆到本地,终端执行如下命令:

      // 这里可以用https或ssh地址方式克隆
      $ pod repo add WBSpecs https://github.com/G***00/TestPodspec.git

      注意:代码仓库和Spec Repo是需要分开存储的

      克隆成功之后,我们可以查看一下:

      $ open ~/.cocoapods/repos

      本地cocoapods目录如下:



    • 向私有的Spec Repo仓库中提交.podspec
      • 首先将本地.podspec推送到远程私有repo spec仓库和本地repo spec仓库,终端执行如下命令:

        $ pod repo push WBSpecs WBAvoidCrash.podspec

        参数解析:repo  spec仓库名称  .podspec名称

      • 验证远程是否通过

        推送成功之后,终端输入如下命令进行验证

        $ pod spec lint WBAvoidCrash.podspec
      • 验证私有仓库是否可用

        用pod命令进行搜索,看能否搜索到:

        $ pod search WBAvoidCrash
      • 如果搜索不到,在终端执行如下命令

        $ rm ~/Library/Caches/CocoaPods/search_index.json

        或者更新本地仓库

        $ pod repo update

        然后重新search

    • 在个人项目中增加刚刚制作好的Podfile并使用
      • 新建一个测试工程测试,用CocoaPods初始化项目,编辑Podfile文件:

        #CocoaPods官方spec仓库
        source 'https://github.com/CocoaPods/Specs.git'
        #自己私有spec仓库
        source 'https://github.com/wenmobo/WBSpecs.git'
        
        platform :ios, '8.0'
        
        target 'TestDemo' do
        #防Crash库
        pod 'WBAvoidCrash'
        end
      • 编辑好podfile文件之后,终端执行:

        $ pod install 安装时使用,更新库使用update命令
        或
        $ pod update 更新时使用
    • 后期的升级维护
      • 更新远程私有库中的代码

      • 修改.podspec中的配置,version升级一个版本

      • 给当前的远程仓库的代码,重新打个tag,tag和.podspec的version一样

      • 远程仓库的代码更新完毕,接下来执行上面的 6.将当前本地的spec文件传到私有Spec Repo仓库的索引库中

      • 检查测试一下,有没有上传到私有Spec Repo仓库的索引库中

  • 删除私有的 Spec Repo
    $ pod repo remove [name]

    其实直接找到以后,手动删除就好了,然后在将Git的变动push到远端仓库即可

  • 清理CocoaPods本地缓存

    特殊情况下,由于网络或者别的原因,通过CocoaPods下载的文件可能会有问题

    • 手动删除(~/Library/Caches/CocoaPods/Pods/Release目录)

    • 打开终端,输入$ pod cache list,会列出所有本地已经缓存的第三方库,在终端中输入$ pod cache clean AAA会删除AAA缓存库,使用$ pod cache clean --all清除所有缓存

三,iOS 创建自己的Cocoapods公有库

  • 配置公有库PodSpec

    配置方式和私有库一致

  • 推送公有库到CocoaPods

    • 通过pod来注册trunk,确认发送到邮箱的邮件,然后查看注册的个人信息。

      # 注册trunk
      pod trunk register 邮箱 ‘用户名’ --description=‘描述’
      # 查看个人信息
      pod trunk me
    • 验证上传的podspec是否有效,若未通过验证可根据提示进行修改。
      # 验证公有库podspec是否有效
      pod spec lint 公有库名称.podspec
    • 将公有库推送到CocoaPods上。
      # 推送公有库到CocoaPods
      pod trunk push 公有库名称.podspec

四,公有库和私有库有什么区别?

  创建公有库和私有库,实际上原理是相同的, 不同的是, 两者的版本索引查询方式,公有库的podspec由CocoaPods/Specs管理,私有库需要自己建立一个仓库来管理podspec

 

posted on 2019-11-26 09:53  梁飞宇  阅读(844)  评论(0编辑  收藏  举报