前言

在从前的一篇文章,环绕 “移动客户端架构规划“这个大论题展开评论的过程中,咱们做了根本的总述,而且针对 架构规划 的大论题简扼地区分为五个部分:

  • 模块化开发
  • 组件化开发
  • 二进制化处理
  • 规划形式
  • 架构规划与架构演进

咱们将在本篇文章,在展开 组件化开发 这个论题之前,先认识一下 组件化开发依靠包办理东西Cocoapods

一、什么是Cocoapods

CocoaPodsSwiftObjective-C Cocoa 项目的依靠办理器

  • 它具有超过 94,000 个库,用于超过 300 万个运用程序。
  • 运用 Cocoapods,能够界说库本身的依靠联系(简称Pods ),以及在整个开发环境中对第三方库的版别办理十分便利。

CocoaPods 开发者 发明该东西的理念 主要体现在两个方面:

  • 首先,在工程中引进第三方代码会涉及到许多内容。
    • 针对 Objective-C 初级开发者来说,工程文件的装备会让人很沮丧
    • 在装备 build phaseslinker flags 过程中,会引起许多人为因素的过错。
    • CocoaPods 简化了这一切,它能够自动装备编译选项
  • 其次,经过 CocoaPods,能够很便利的查找到新的第三方库。
    • 当然,这并不是说你能够简略的将他人供给的库拿来拼凑成一个运用程序。
    • 它的真实作用是让你能够找到真实好用的库,以此来缩短咱们的开发周期和提高软件的质量

二、Cocoapods作业流及办理开发包的几种方法

引进一张图,快速认识 CocoaPods 作业流程:

03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

相关名词介绍

2.1 长途索引库

长途索引库 里寄存的是各种结构的描绘信息,这个库保管在 Github 上,地址如下: github.com/CocoaPods/S…

  • 每个结构下有数个版别,每个版别有一个 json 格局的描绘信息,如下:
    {
      "name": "CAIStatusBar",
      "version": "0.0.1",
      "summary": "A simple indicator",
      "homepage": "https://github.com/apple5566/CAIStatusBar.git",
      "license": "MIT",
      "authors": {
        "apple5566": "zaijiank110@sohu.com"
      },
      "platforms": {
        "ios": "6.0"
      },
      "source": {
        "git": "https://github.com/apple5566/CAIStatusBar.git",
        "tag": "0.0.1"
      },
      "source_files": "CAIStatusBar/**/*.{h,m}",
      "resources": "CAIStatusBar/CAIStatusBar.bundle",
      "requires_arc": true
    }
    
  • 其间 git 字段表明该结构的保管地址,也便是上面时序图中的 长途结构库

2.2 本地索引库

install cocoapods 指令后,需求履行 pod setup 这个指令,pod setup 指令便是将长途索引库克隆到本地来,本地索引库的途径如下:

~/.cocoapods/repos/master

本地索引库和长途索引库的目录一致,结构如下:

03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

2.3 本地索引文件

当履行 pod search 指令时,假如本地索引文件不存在,会创立这个文件。

pod search afn
Creating search index for spec repo 'master'..

假如这个文件存在,则会在此文件中进行索引,承认所需求的结构是否存在,本地索引文件的途径如下:

~/Library/Caches/CocoaPods

咱们在前面的总述部分,现已简扼地介绍了库的几种区分,咱们在这里用一个表格来进一步直观描绘:

本地库长途库

本地库 长途库
私有库 开发者本地寄存 git服务器是私有云
公有库 git服务器是公有云

闭源库开源库

闭源库 开源库
公有库/私有库 代码二进制化处理(.a/.framework/.xcframework) 源码、资源文件悉数公开

三、在Mac上搭载Cocoapods环境

3.1 在Intel芯片的Mac上装置

1. 装置好Ruby环境/晋级ruby环境

  • 1.1 装置RVM: RVM 是一个快捷的多版别 Ruby 环境的办理和切换东西 官网:rvm.io/
    • Mac 中装置 Ruby 需求先装置好 RVM
      • 装置RVM:
         curl -ssl https://get.rvm.io | bash -s stable
        
      • 载入 RVM 环境:
            source ~/.rvm/scripts/rvm
        
      • 修正 RVM 下载 Ruby 的源 为 Ruby China 镜像:
            echo "ruby_url=<https://cache.ruby-china.com/pub/ruby>" > ~/.rvm/user/db
        
      • 查看装置结果(假如能显现版别号,则装置成功 ):
            rvm -v
           ##打印以下结果,代表装置成功: rvm 1.29.9 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [<https://rvm.io/]> 
        
  • 1.2 假如之前装置过 RVM, 则进行RVM 更新:
      rvm get stable
    
  • 1.3 装置 Ruby
    • 1.3.1 列出 Ruby 可装置的版别信息:
          rvm list known
      
    • 1.3.2 装置一个 Ruby 版别
          rvm install 2.6.0
      
    • 1.3.3 假如想设置为默许版别,能够用这条指令来完结:
          rvm use 2.6.0 --default
      
    • 1.3.4 检测一下Ruby:
          ruby -v
      
      03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
    1. 运用ruby-chinaRuby镜像源
    • 2.1 查看当时Ruby源
         gem sources -l
      
    • 2.2 移除旧的Ruby源
        gem sources --remove https://rubygems.org/
      
    • 2.2 添加新的Ruby源
        gem sources -a https://gems.ruby-china.com/
      
    • 2.3 验证Ruby源是不是Ruby-china
        gem sources -l
      
    1. 装置CocoaPods
        sudo gem install -n /usr/local/bin cocoapods
    
    1. 假如装置了多个Xcode运用下面的指令挑选(一般需求挑选较新的Xcode版别)
      sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
    
    1. 装置本地库
        pod setup
    
    • 该过程是在下载Cocoapods官方团队办理的一切长途库索引文件到本地
    • 库保管在 Github 上,地址如下: github.com/CocoaPods/S…
    • 若是能够有索引文件的国内镜像库或许现成的索引文件库文件包,能够直接复制放到本地的文件夹
    • 文件夹地址查询指令行: pod repo
      • 查询装置进度指令行
        • cd ~/.cocoapods
        • du -sh *

3.2 在M系列(M1、M1 Pro、M2……)芯片的Mac上装置

  • Cocoapods
    • 装置Cocoapods
          sudo gem install -n /usr/local/bin cocoapods
      
    • 挑选Xcode版别 (假如装置了多个Xcode版别,运用下面的指令挑选(引荐挑选最近的Xcode版别))
        sudo xcode-select-switch/Applications/Xcode.app/Contents/Developer
    
    • 装置本地
      Mac OS Catalina开端,终端履行上面指令后就直接结束了
      咱们需求手动装置本地库:
      // 国外地址,假如你能科学上网的话,能够运用这个方法
      git clone https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/trunk
      // 清华大学镜像,速度杠杠的,引荐运用
      git clone https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git  ~/.cocoapods/repos/trunk
      

四、Cocoapods的详细运用

4.1 了解Cocoapods在日常开发中的的详细运用

  1. 作为开发包办理东西:
    • 用于 办理 【二方库、三方库(SDK)】依靠包
    • 用于 公司 项目团队内部 组件化开发 办理 公司移动开发套件的【私有库】
    • 开发包 的 办理 除了 库 本身的 代码集成外,还包含【版别控制、编译依靠设置】等
  2. 能够 与 Fastlane + Jenkins 等东西组合 成 简易的 继续集成渠道
  3. ……

4.2 开始了解.podspec文件

经过Cocoapods保管的一切依靠包(咱们往常称之为Pod库),他们都需求凭借一个描绘文件来办理:.podspec

  • 运用他人开发的Pod库时,咱们经过搜索指令pod search、或集成指令pod install…等指令需求填的 库信息 都是 他人在 他们 发布一个Pod库时,在.podspec写好的;(若是咱们仅仅运用他人的库,能够恰当阅览他人的.podspec)
  • 反之,咱们若是想发布归于咱们公司团队的Pod库,咱们也要写好自己Pod库.podspec文件,用于约束和办理咱们的Pod库

pod spec 指令创立结构的描绘文件``.podspec,文档如下: guides.cocoapods.org/syntax/pods…

创立并开始了解.podspec文件

咱们创立一个文件夹命名为NKTestLib
现在在 NKTestLib 目录下履行创立.podspec文件的指令:

pod spec create NKTestLib

创立出来的描绘文件:

#
# Be sure to run `pod spec lint NKTestLib.podspec' to ensure this is a
# valid spec and to remove all comments including this before submitting the spec.
#
# To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html
# To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
#
Pod::Spec.new do |spec|
 # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # These will help people to find your library, and whilst it
 # can feel like a chore to fill in it's definitely to your advantage. The
 # summary should be tweet-length, and the description more in depth.
 #
  spec.name     = "NKTestLib"
 spec.version   = "0.0.1"
 spec.summary   = "This is a Pod Lib Demo for blog."
 # 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!
 spec.description = "一般描绘库的用处、主要功用等"
 spec.homepage   = "https://github.com/VanZhang-CN-SZ-SN9037/NKTestLib"
 # spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
 # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # Licensing your code is important. See https://choosealicense.com for more info.
 # CocoaPods will detect a license file if there is a named LICENSE*
 # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
 #
  spec.license   = { :type => "MIT", :file => "./LICENSE" }
 # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # Specify the authors of the library, with email addresses. Email addresses
 # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
 # accepts just a name if you'd rather not provide an email address.
 #
 # Specify a social_media_url where others can refer to, for example a twitter
 # profile URL.
 #
  spec.author       = { "Van Zhang" => "toBeABetterManZxh91@gmail.com" }
 # Or just: spec.author  = "Van Zhang"
 # spec.authors      = { "Van Zhang" => "Van.Zhang@nike.com" }
 # spec.social_media_url  = "https://twitter.com/Van Zhang"
 # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # If this Pod runs only on iOS or OS X, then specify the platform and
 # the deployment target. You can optionally include the target after the platform.
 #
  spec.platform   = :ios, "14.0"
 # spec.platform   = :ios, "5.0"
  # When using multiple platforms
 spec.ios.deployment_target = "14.0"
 # spec.osx.deployment_target = "10.7"
 # spec.watchos.deployment_target = "2.0"
 # spec.tvos.deployment_target = "9.0"
 spec.swift_version = "5.4"
 # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # Specify the location from where the source should be retrieved.
 # Supports git, hg, bzr, svn and HTTP.
 #
  spec.source    = { :git => "git@github.com:VanZhang-CN-SZ-SN9037/NKTestLib.git", :tag => "#{spec.version}" }
 # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # CocoaPods is smart about how it includes source code. For source files
 # giving a folder will include any swift, h, m, mm, c & cpp files.
 # For header files it will include any header in the folder.
 # Not including the public_header_files will make all headers public.
 #
 spec.source_files = "Classes", ".//Classes/*.{c,h,m,mm,swift}"
 spec.exclude_files = "Classes/Exclude"
 spec.public_header_files = "Classes/**/*.h"
 # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # A list of resources included with the Pod. These are copied into the
 # target bundle with a build phase script. Anything else will be cleaned.
 # You can preserve files from being cleaned, please don't preserve
 # non-essential files like tests, examples and documentation.
 #
 # spec.resource = "icon.png"
 spec.resources = "Classes/Resources/*"
 # spec.preserve_paths = "FilesToSave", "MoreFilesToSave"
 # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # Link your library with frameworks, or libraries. Libraries do not include
 # the lib prefix of their name.
 #
 # spec.framework = "SomeFramework"
 spec.frameworks = ['CoreTelephony','CoreFoundation','AdSupport','AppTrackingTransparency']

 # spec.library  = "iconv"
 spec.libraries = ['c++', 'resolv.9']
 # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # If your library depends on compiler flags you can set them in the xcconfig hash
 # where they will only apply to your library. If you depend on other Podspecs
 # you can include multiple dependencies to ensure it works.
 # spec.requires_arc = true
 # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
 spec.static_framework = true
 spec.vendored_frameworks = 'Classes/Vendor/AliTigerTally_IDFA.xcframework'
 spec.dependency "Alamofire", "~>5"
end

目录下会创立一个 NKTestLib.podspec 文件,然后修正这个文件,主要有以下几个字段:

  • version: 这个 spec 映射的版别,保证 Gitreleases 与此对应;
  • homepage: 项目主页;
  • source: 结构源代码的保管地址;
  • tag:与 version 对应;
  • source_files: 结构源代码的目录、文件、文件类型等规则;

在 开发Pod库 过程中,需求用到的描绘文件字段:

  • ios.deployment_target: 集成本库,运转运用,要求的系统和最低系统版别
  • swift_version: 约束编译库的Swift版别;
  • resources: 图片等文件资源寄存途径
  • frameworks: 需求依靠的系统.framework库
  • libraries: 需求依靠的系统.tbd库
  • static_framework: 传布尔值,描绘本Pod库是不是要创立一个文件夹用于寄存 .framework静态库
  • vendored_frameworks: 传入第三方库(xxx.framework/xxx.xcframework)的寄存途径,集成的时分,会复制该途径下的库到framework这个文件夹内
  • vendored_library:传入第三方库(xxx.a)的寄存途径,集成的时分,会复制该途径下的库到framework这个文件夹内
  • dependency: 依靠库(一般写长途依靠库称号即可)
  • compiler_flags:编译设置(如警告忽略,宏设置)
         spec.compiler_flags = '-Wno-format', '-DOS_OBJECT_USE_OBJC=0'
    
  • prefix_header_contents:pch预编译头文件内容
         spec.prefix_header_contents = '#import <UIKit/UIKit.h>'
    
  • prefix_header_file pch预编译头文件途径
        spec.prefix_header_file = 'iphone/include/prefix.pch'
    

五、制造Cocoapods库

在介绍制造Cocoapods库之前,咱们先回顾一下 CocoaPods 作业流程:

03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
上面的流程清楚以后,制造 CocoaPods 库相信应该不会太难了,大致分为以下几步:

  1. 保管结构源码到 Git
  2. 创立结构描绘信息XXX.podspec;
  3. 上传结构描绘信息到 https://github.com/CocoaPods/Specs
  4. 指令行 pod setup , 创立本地索引库;
  5. 指令行 pod install ,将结构集成到项目中;

5.1 进一步了解.podspec 文件的语法

长时间不写Podspec文件,简单忘记里边的一些特点意义,所以本文把官方Podspec语法v1.9.0翻译出来而且加上了一部分自己的理解,便利后续在用到的时分能够直接拿过来看。

5.1.1 Root specification

root标准存储了相关库特定版别的信息。

下面的特点只能写在root标准上,而不能写在“sub-spec”上。

必填字段:

  • .name:
    pod search 搜索的关键词,这里必定要和.podspec的称号相同,否则会报错;
    spec.name = 'AFNetworking'
    
  • .version:
    Pod库最新的版别
    spec.version = '0.0.1'
    
  • .authors:
    库保护者(而不是Podspec保护者)的称号和电子邮件地址
    spec.author = 'Darth Vader'
    spec.authors = 'Darth Vader', 'Wookiee'
    spec.authors = { 'Darth Vader' => 'darthvader@darkside.com',
                     'Wookiee'     => 'wookiee@aggrrttaaggrrt.com' }
    
  • .license:
    Pod的答应证
    除非源中包含一个名为LICENSE.*LICENCE.*的文件,否则必须指定答应证文件的途径通常用于答应证类型的通知的完整文本。
    假如指定了答应文件,它要么必须是没有文件扩展名或许是一个txtmdmarkdown
    spec.license = 'MIT'
    spec.license = { :type => 'MIT', :file => 'MIT-LICENSE.txt' }
    spec.license = { :type => 'MIT', :text => <<-LICENSE
                       Copyright 2012
                       Permission is granted to...
                     LICENSE
                   }
    
  • .homepage:
    Pod主页的URL
    spec.homepage = 'http://www.example.com'
    
  • .source:
    寄存检索库的git仓地址方位
    1. 运用标签指定Git来历。多数Podspecs是这样写的。
    spec.source = { :git => 'https://github.com/AFNetworking/AFNetworking.git',
                    :tag => spec.version.to_s }
    
    1. 运用以’v’和子模块为前缀的标签。
    spec.source = { :git => 'https://github.com/typhoon-framework/Typhoon.git',
                    :tag => "v#{spec.version}", :submodules => true }
    
    1. 运用带标记的Subversion。
    spec.source = { :svn => 'http://svn.code.sf.net/p/polyclipping/code', :tag => '4.8.8' }
    
    1. 运用与标准的语义版别字符串相同版别的Mercurial。
    spec.source = { :hg => 'https://bitbucket.org/dcutting/hyperbek', :revision => "#{s.version}" }
    
    1. 运用HTTP下载代码的压缩文件。它支撑zip,tgz,bz2,txz和tar。
    spec.source = { :http => 'http://dev.wechatapp.com/download/sdk/WeChat_SDK_iOS_en.zip' }
    
    1. 运用HTTP下载文件,并运用哈希来验证下载。它支撑sha1和sha256。
    spec.source = { :http => 'http://dev.wechatapp.com/download/sdk/WeChat_SDK_iOS_en.zip',
                    :sha1 => '7e21857fe11a511f472cfd7cfa2d979bd7ab7d96' }
    
    咱们一般比较常用的便是方法1了,也有2和3
  • .summary:
    简短说明(最多140个字符),该摘要应恰当大写并包含正确的标点符号
    spec.summary = 'Computes the meaning of life.'
    

选填字段:

  • .swift_versions:
    支撑的Swift版别。CocoaPods将版别“ 4”视为“ 4.0”,而不是“ 4.1”或“ 4.2”
    留意Swift编译器主要承受主要版别,有时会承受次要版别。尽管CocoaPods允许指定次要版别或补丁版别,但Swift编译器可能不会彻底认可它。
    咱们一般是直接指定版别

    spec.swift_versions = ['3.0']
    spec.swift_versions = ['3.0', '4.0', '4.2']
    spec.swift_version = '3.0'
    spec.swift_version = '3.0', '4.0'
    
  • .cocoapods_version:
    所支撑的CocoaPods版别,比方某个特点,是某个cocoapods版别以上才有的,这个时分进行依靠装置,就需求指定版别。

    spec.cocoapods_version = '>= 0.36'
    
  • .social_media_url:
    Pod、CocoaPods Web服务的交际媒体联系人的URL能够运用此URL

    spec.social_media_url = 'https://twitter.com/cocoapods'
    spec.social_media_url = 'https://groups.google.com/forum/#!forum/cocoapods'
    
  • .description:
    比摘要更详细的说明,用这个字段。咱们一般会有README.md和CHANGELOG.md、CODEOWNERS等文件更详细说明来替代它。看你的团队怎么挑选

    spec.description = <<-DESC
                         Computes the meaning of life.
                         Features:
                         1. Is self aware
                         ...
                         42. Likes candies.
                       DESC
    
  • .screenshots:
    展现Pod图片的网址列表。用于面向UI库。CocoaPods主张运用gif格局。

    spec.screenshot  = ''
    spec.screenshots = [ 
    '',
    '' ]
    
  • .documentation_url:
    Pod文档的可选URL,CocoaPods网络媒体资源将运用该URL。将其保存为空白将默以为您的库CocoaDocs生成URL

    spec.documentation_url = 'http://www.example.com/docs.html'
    
  • .prepare_command:
    下载Pod后将履行的bash脚本。该指令可用于创立,删去和修正下载的任何文件,而且将在搜集标准其他文件特点的任何途径之前运转。

    在清理Pod和创立Pods项目之前,将履行此指令。作业目录是Pod的根目录。

    假如pod装置了该:path选件,则不会履行此指令。

    spec.prepare_command = 'ruby build_files.rb'
    spec.prepare_command = <<-CMD
                            sed -i 's/MyNameSpacedHeader/Header/g' ./**/*.h
                            sed -i 's/MyNameOtherSpacedHeader/OtherHeader/g' ./**/*.h
                       CMD
    
  • .static_framework:
    use_frameworks!假如指定,则pod应当包含静态库结构。

    spec.static_framework = true
    
  • .deprecated:
    是否已废弃该库

    spec.deprecated = true
    
  • .deprecated_in_favor_of:
    不支撑运用的Pod称号

    spec.deprecated_in_favor_of = 'NewMoreAwesomePod'
    

5.1.2 Platform相关

主要是指明支撑当时库的渠道和相应的布置target。

  • .Platform:
    支撑此Pod的渠道。保存此空白表明Pod在一切渠道上都支撑。当支撑多个渠道时,应改为运用以下deployment_target。
spec.platform = :osx, '10.8'
spec.platform = :ios
spec.platform = :osx
  • .Platdeployment_targetform:
    支撑渠道的最低布置target。

    platform特点相反,deployment_target特点允许指定支撑该Pod的多个渠道-为每个渠道指定不同的布置方针。
    spec.ios.deployment_target = '6.0'
    spec.osx.deployment_target = '10.8'
    

5.1.3 Build settings相关

构建环境的装备相关设置

  • .dependency:
    对其他Pod或“sub-spec”的依靠。依靠联系能够指定版别要求

    spec.dependency 'AFNetworking', '~> 1.0'
    spec.dependency 'AFNetworking', '~> 1.0', :configurations => ['Debug']
    spec.dependency 'AFNetworking', '~> 1.0', :configurations => :debug
    spec.dependency 'RestKit/CoreData', '~> 0.20.0'
    spec.ios.dependency 'MBProgressHUD', '~> 0.5'	
    
  • .info_plist:
    要添加到生成的键值对Info.plist

    这些值将与CocoaPods生成的默许值兼并,然后覆盖一切重复项。

    关于库标准,值将兼并到为运用结构集成的库生成的Info.plist中。它对静态库无效。

    不支撑sub-spec(运用和测验spec除外)。

    关于运用程序标准,这些值将兼并到运用程序主机的中Info.plist

    关于测验spec,这些值将兼并到测验包的中Info.plist

    spec.info_plist = {
      'CFBundleIdentifier' => 'com.myorg.MyLib',
      'MY_VAR' => 'SOME_VALUE'
    }
    
  • .requires_arc:
    允许您指定运用ARC的source_files。它能够是支撑ARC的文件,也能够是true,以表明一切source_files都运用ARC。

    不运用ARC的文件将带有-fno-objc-arc编译器标志。

    此特点的默许值为true

    # 默许
    spec.requires_arc = true 
    # 设置
    spec.requires_arc = false
    spec.requires_arc = 'Classes/Arc'
    spec.requires_arc = ['Classes/*ARC.m', 'Classes/ARC.mm']
    
  • .frameworks:
    当时target所需系统framework列表

    spec.ios.framework = 'CFNetwork'
    spec.frameworks = 'QuartzCore', 'CoreData'
    
  • .weak_frameworks:
    当时target所需“弱引证”的framework列表

    spec.weak_framework = 'Twitter'
    spec.weak_frameworks = 'Twitter', 'SafariServices'
    
  • .libraries:
    当时target所需系统library列表

    spec.ios.library = 'xml2'
    spec.libraries = 'xml2', 'z'
    
  • .compiler_flags:
    传递给编译器的flag

    spec.compiler_flags = '-DOS_OBJECT_USE_OBJC=0', '-Wno-format'
    
  • .pod_target_xcconfig:
    要添加到最终私有pod方针xcconfig文件的任何标志。

    spec.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-lObjC' }
    
  • .user_target_xcconfig:
    不引荐运用

  • .prefix_header_contents:
    不引荐运用

  • .prefix_header_file:
    不引荐运用

  • .module_name:
    用于该spec的结构/ clang模块的称号,而不是默许的称号(假如设置,则为header_dir,否则为标准称号)。

spec.module_name = 'Three20'
  • .header_dir:
    头文件的存储目录。
spec.header_dir = 'Three20Core'
  • .header_mappings_dir:
    用于保存头文件的文件夹结构的目录。假如未供给,则将头文件展平。
spec.header_mappings_dir = 'src/include'
  • .script_phases:
    此特点允许界说脚本,以作为Pod编译的一部分履行。与prepare指令不同,脚本作为xcodebuild的一部分履行,也能够运用在编译期间设置的一切环境变量。

    Pod能够供给要履行的多个脚本,而且将按照声明的顺序添加它们,并考虑它们的履行方位设置。

    留意为了供给对一切脚本内容的可见性和认识,假如装置了Pod包含任何脚本,则会在装置时向用户显现警告。
spec.script_phase = { :name => 'Hello World', :script => 'echo "Hello World"' }
spec.script_phase = { :name => 'Hello World', :script => 'echo "Hello World"', :execution_position => :before_compile }
spec.script_phase = { :name => 'Hello World', :script => 'puts "Hello World"', :shell_path => '/usr/bin/ruby' }
spec.script_phase = { :name => 'Hello World', :script => 'echo "Hello World"',
  :input_files => ['/path/to/input_file.txt'], :output_files => ['/path/to/output_file.txt']
}
spec.script_phase = { :name => 'Hello World', :script => 'echo "Hello World"',
  :input_file_lists => ['/path/to/input_files.xcfilelist'], :output_file_lists => ['/path/to/output_files.xcfilelist']
}
spec.script_phases = [
    { :name => 'Hello World', :script => 'echo "Hello World"' },
    { :name => 'Hello Ruby World', :script => 'puts "Hello World"', :shell_path => '/usr/bin/ruby' },
  ]

5.1.4 File patterns相关

文件途径相关设置;不支撑遍历父目录

  • *匹配一切文件
  • c*匹配一切以c最初的文件
  • *c匹配一切以c结束的文件
  • *c*将匹配其间包含c的一切文件(包含最初或结束)

podspec字段:

  • .source_files:
    需求包含的源文件寄存途径
    spec.source_files = 'Classes/**/*.{h,m}'
    spec.source_files = 'Classes/**/*.{h,m}', 'More_Classes/**/*.{h,m}'
    
  • .public_header_files:
    用作公共头的文件形式列表。

    这些形式与源文件匹配,以包含将公开给用户项目并从中生成文档的标头。构建库时,这些头将出现在构建目录中。假如未指定公共头,则将source_files中的一切头视为公共。
    spec.public_header_files = 'Headers/Public/*.h'
    
  • .private_header_files:
    用来标记私有文件形式列表。

    这些形式与公共标头(假如未指定公共标头,则与一切标头)匹配,以扫除那些不该露出给用户项目而且不运用于生成文档的标头。构建库时,这些头将出现在构建目录中。

    没有列出为公共和私有的头文件将被视为私有,但除此之外根本不会出现在构建目录中。
    spec.private_header_files = 'Headers/Private/*.h'
    
  • .vendored_frameworks:
    源文件相关联的第三方framework
    spec.ios.vendored_frameworks = 'Frameworks/MyFramework.framework'
    spec.vendored_frameworks = 'MyFramework.framework', 'TheirFramework.framework'
    
  • .vendored_libraries:
    源文件相关联的第三方libraries
    spec.ios.vendored_library = 'Libraries/libProj4.a'
    spec.vendored_libraries = 'libProj4.a', 'libJavaScriptCore.a'
    
  • .resource_bundles:
    为了将Pod构建为静态库,官方强烈主张运用此特点来办理资源文件,由于运用resources特点可能会发生称号抵触。

    资源文件bundle的称号至少应包含Pod的称号,以最大程度地减少称号抵触的可能性。
    spec.ios.resource_bundle = { 'MapBox' => 'MapView/Map/Resources/*.png' }
    spec.resource_bundles = {
    'MapBox' => ['MapView/Map/Resources/*.png'],
    'MapBoxOtherResources' => ['MapView/Map/OtherResources/*.png']
    }
    
  • .resources:
    复制到target中的资源列表。

    为了将Pod构建为静态库,官方主张是运用resource_bundle,由于运用resources特点可能会发生称号抵触。此外,运用此特点指定的资源将直接复制到客户端方针,因而Xcode不会对其进行优化。
    spec.resource = 'Resources/HockeySDK.bundle'
    spec.resources = ['Images/*.png', 'Sounds/*']
    
  • .exclude_files:
    从其他文件形式中扫除的文件形式列表。

    比方在设置某个子模块的时分,不需求包含其间的一些文件,就能够经过这个特点来进行设置。
    spec.ios.exclude_files = 'Classes/osx'
    spec.exclude_files = 'Classes/**/unused.{h,m}'
    
  • .preserve_paths:
    任何被下载的文件之后是不会被移除。

    默许情况下,CocoaPods会移除一切与其他任何文件形式都不匹配的文件。
    spec.preserve_path = 'IMPORTANT.txt'
    spec.preserve_paths = 'Frameworks/*.framework'
    
  • .module_map:
    将此Pod集成为结构时应运用的模块映射文件。

    默许情况下,CocoaPods依据标准中的公共头创立模块映射文件。
    spec.module_map = 'source/module.modulemap'
    

5.1.5 Subspecs相关

一个库能够指定依靠在另一个库、另一个库的子标准或本身的子标准上。
详细看下面这个例子:

pod 'ShareKit', '2.0'
pod 'ShareKit/Twitter',  '2.0'
pod 'ShareKit/Pinboard', '2.0'

咱们有时分会编写这样的Podfile文件,导入第三方或许自己依靠的库;那么它对应的podspec文件应该怎么编写呢?

如下:

subspec 'Twitter' do |sp|
  sp.source_files = 'Classes/Twitter'
end
subspec 'Pinboard' do |sp|
  sp.source_files = 'Classes/Pinboard'
end

这样写就能够了,指定对应的源关联文件或许资源文件即可。

留意一点,便是经过pod search的时分只能是整个模块,即你不能独自搜索里边的子模块,可是咱们podfile依靠是能够指定详细依靠哪一个模块。

  • .default_subspecs:
    指定默许的依靠,假如不指定就依靠悉数子依靠。
    spec.default_subspec = 'Core'
    spec.default_subspecs = 'Core', 'UI'
    spec.default_subspecs = :none
    

5.1.6 Multi-Platform support

设置支撑的某个渠道,比方ios、osx、tvos等

spec.ios.source_files = 'Classes/ios/**/*.{h,m}'
spec.osx.source_files = 'Classes/osx/**/*.{h,m}'
spec.osx.source_files = 'Classes/osx/**/*.{h,m}'
spec.tvos.source_files = 'Classes/tvos/**/*.{h,m}'
spec.watchos.source_files = 'Classes/watchos/**/*.{h,m}'

假如想要知道自己编写的podspec文件是否合法有用,能够经过指令pod spec lint进行验证。

5.2 CocoaPods本地库(只有一个主库)

现在开端动手吧!

  • 首先,前面创立的NKTestLib 目录下新建一个 Classes 目录,用来寄存结构源码;(能够给 Classes 目录任意的命名,Classes 仅仅一种约定俗成的命名)
  • 然后,将 NKTestLib 保管到 Git

本地库:
在当时设备创立一个库房,源码以及相关的资源文件存储在当时电脑,用本地途径导入相关的工程,进行集成运用

~/Desktop/NKTestLib

03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

接着创立一个壳工程,现在你的方针是运用 pod 的方法,将 NKTestLib 这个库集成到壳工程中。

1.创立库描绘文件

和公开库相同,咱们需求先创立一个 spec 文件,指令如下:

pod spec create NKTestLib

修正 NKTestLib.podspec 文件,修正成下面这样:

#
# Be sure to run `pod spec lint NKTestLib.podspec' to ensure this is a
# valid spec and to remove all comments including this before submitting the spec.
#
# To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html
# To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
#
Pod::Spec.new do |spec|
 # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # These will help people to find your library, and whilst it
 # can feel like a chore to fill in it's definitely to your advantage. The
 # summary should be tweet-length, and the description more in depth.
 #
  spec.name     = "NKTestLib"
 spec.version   = "0.0.1"
 spec.summary   = "This is a Pod Lib Demo for blog."
 # 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!
 spec.description = "一般描绘库的用处、主要功用等"
 spec.homepage   = "https://github.com/VanZhang-CN-SZ-SN9037/NKTestLib"
 # spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
 # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # Licensing your code is important. See https://choosealicense.com for more info.
 # CocoaPods will detect a license file if there is a named LICENSE*
 # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
 #
  spec.license   = { :type => "MIT", :file => "./LICENSE" }
 # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # Specify the authors of the library, with email addresses. Email addresses
 # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
 # accepts just a name if you'd rather not provide an email address.
 #
 # Specify a social_media_url where others can refer to, for example a twitter
 # profile URL.
 #
  spec.author       = { "Van Zhang" => "toBeABetterManZxh91@gmail.com" }
 # Or just: spec.author  = "Van Zhang"
 # spec.authors      = { "Van Zhang" => "Van.Zhang@nike.com" }
 # spec.social_media_url  = "https://twitter.com/Van Zhang"
 # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # If this Pod runs only on iOS or OS X, then specify the platform and
 # the deployment target. You can optionally include the target after the platform.
 #
  spec.platform   = :ios, "14.0"
 # spec.platform   = :ios, "5.0"
  # When using multiple platforms
 spec.ios.deployment_target = "14.0"
 # spec.osx.deployment_target = "10.7"
 # spec.watchos.deployment_target = "2.0"
 # spec.tvos.deployment_target = "9.0"
 spec.swift_version = "5.4"
 # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # Specify the location from where the source should be retrieved.
 # Supports git, hg, bzr, svn and HTTP.
 #
  spec.source    = { :git => "git@github.com:VanZhang-CN-SZ-SN9037/NKTestLib.git", :tag => "#{spec.version}" }
 # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # CocoaPods is smart about how it includes source code. For source files
 # giving a folder will include any swift, h, m, mm, c & cpp files.
 # For header files it will include any header in the folder.
 # Not including the public_header_files will make all headers public.
 #
 spec.source_files = "Classes", ".//Classes/*.{c,h,m,mm,swift}"
 spec.exclude_files = "Classes/Exclude"
 spec.public_header_files = "Classes/**/*.h"
 # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # A list of resources included with the Pod. These are copied into the
 # target bundle with a build phase script. Anything else will be cleaned.
 # You can preserve files from being cleaned, please don't preserve
 # non-essential files like tests, examples and documentation.
 #
 # spec.resource = "icon.png"
 spec.resources = "Classes/Resources/*"
 # spec.preserve_paths = "FilesToSave", "MoreFilesToSave"
 # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # Link your library with frameworks, or libraries. Libraries do not include
 # the lib prefix of their name.
 #
 # spec.framework = "SomeFramework"
 spec.frameworks = ['CoreTelephony','CoreFoundation','AdSupport','AppTrackingTransparency']

 # spec.library  = "iconv"
 spec.libraries = ['c++', 'resolv.9']
 # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
 #
 # If your library depends on compiler flags you can set them in the xcconfig hash
 # where they will only apply to your library. If you depend on other Podspecs
 # you can include multiple dependencies to ensure it works.
 # spec.requires_arc = true
 # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
 spec.static_framework = true
 spec.vendored_frameworks = 'Classes/Vendor/AliTigerTally_IDFA.xcframework'
 spec.dependency "Alamofire", "~>5"
end

现在你的本地库现已预备结束了,下面就能够运用这个库了。

2. 导入本地私有库

现在进入到壳工程目录下,履行指令:

pod init

修正 Podfile 文件,如下:

# Uncomment the next line to define a global platform for your project

# platform :ios, '9.0'
target 'TempDemo' do

 # Comment the next line if you don't want to use dynamic frameworks
 use_frameworks!
 pod 'NKTestLib',:path=>"/Users/VZha33/Desktop/NKTestLib/NKTestLib.podspec"
 # Pods for TempDemo
end

这里有一个 path 关键字,它表明在 pod install 履行时,在指定的途径下寻觅 NetWork.podspec 文件。

下面履行 pod install 指令,提示信息如下:

pod install
Analyzing dependencies
Downloading dependencies
Installing Alamofire (5.6.4)
Installing NKTestLib (0.0.1)
Generating Pods project
Integrating client project
Pod installation complete! There is 1 dependency from the Podfile and 2 total pods installed.

03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
现在 NKTestLib 这个库就集成到了壳工程中。

与运用长途库不同,本地库的源文件会在 Development Pods 这个目录下,而不是 Pods 目录,趁便一提,CocoaPods 的库开发,一般也是这样树立环境的,开发完结后再修正 spec 文件,将其 pull request 到长途索引库。

5.3 CocoaPods本地库 (主库+子库)

若在项目中,咱们并不需求集成 一个 Pod库的一切功用,只需用到其间一部分功用,咱们能够将主库按照不同的功用责任,进一步细化为若干子库,并在方针项目中按需集成。

将主库区分为若干子库:

咱们将前面的示例,运用的NKTestLib进一步区分为不同的子库:

  • 修正NKTestLib.podspec文件(为了简练便于阅览,删掉文件中的部分注释):
    Pod::Spec.new do |spec|
      # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      spec.name     = "NKTestLib"
      spec.version   = "0.0.1"
      spec.summary   = "This is a Pod Lib Demo for blog."
      spec.description = "一般描绘库的用处、主要功用等"
      spec.homepage   = "https://github.com/VanZhang-CN-SZ-SN9037/NKTestLib"
    
      # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      spec.license   = { :type => "MIT", :file => "./LICENSE" }
    
      # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      spec.author       = { "Van Zhang" => "toBeABetterManZxh91@gmail.com" }
    
      # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      spec.platform   = :ios, "14.0"
      spec.swift_version = "5.4"
    
      # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      spec.source    = { :git => "git@github.com:VanZhang-CN-SZ-SN9037/NKTestLib.git", :tag => "#{spec.version}" }
    
      # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #spec.source_files = "Classes", ".//Classes/*.{c,h,m,mm,swift}"
      #spec.exclude_files = "Classes/Exclude"
      spec.public_header_files = "Classes/**/*.h"
    
      # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      spec.resources = "Assets/*"
    
      # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      spec.frameworks = ['CoreTelephony','CoreFoundation','AdSupport','AppTrackingTransparency']
      spec.libraries = ['c++', 'resolv.9']
    
      # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      spec.static_framework = true
      spec.vendored_frameworks = 'Classes/Vendor/AliTigerTally_IDFA.xcframework'
    
      #spec.dependency "Alamofire", "~>5"
    
      # ――― Sub Spec Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      spec.subspec 'Network' do |n|
        n.source_files = 'Classes/Network/**/*'
        n.dependency 'Alamofire'
        n.dependency 'SDWebImage'
      end
      spec.subspec 'Extension' do |e|
        e.source_files = 'Classes/Extension/**/*'
      end
      spec.subspec 'Plugin' do |p|
        p.source_files = 'Classes/Plugin/**/*'
      end
      spec.subspec 'CommerceUI' do |c|
        c.source_files = 'Classes/CommerceUI/**/*'
      end
    end
    
    • 留意子库的区分语法(子库中一切装备项与主库无差异,只需求将装备项前面的Spec命名替换为子库的即可):
      主库Spec命名.subspec '子库称号' do |子库Spec命名|
        ##示例: 子库的源码途径
        子库Spec命名.source_files = '资源途径'
        ...
      end
    
  • 在本次示例中,将主库进一步区分为4个子库:NetworkExtensionPluginCommerceUI
  • 在需求 集成 Pod库的项目中,按需集成:
    • 悉数集成:
      03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
      03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
    • 集成其间任一子库:
      03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
      • 集成子库的pod指令写法:
          pod '主库/子库',:path=>"XXX.podspec的本地途径"
          #或许 
          pod '主库',:path=>"XXX.podspec的本地途径",:subspecs => ['子库的Spec称号']
      
      03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
      03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 若是咱们有许多个Pod主库,且其间若干个Pod主库内部都有相同的功用,比方网络处理功用,咱们还能够把网络处理功用独立出来做一个主库,供给给其它库作为依靠项
  • 若是咱们的开发套件比较完善,同一套事务计划,共用同一套变成接口,但会依据不同的需求运用不同的完结计划,咱们常常会把库的Interface编程接口Implement事务完结,分别作为一个主库
    • 需求依据不同的需求,运用不同厂商的SDK服务:
    • 一个 项目里边有国际化要求 ,同一类服务在不同的国家地区运用契合法律法规的第三方SDK依靠包进行完结(如电商事务、物流事务,有国内与海外服务)
    • 在同一个事务领域,针对不同的供应商的用户群,相似的事务需求 有必定的定制化事务需求 (如金融领域的银行事务,其金融产品:稳妥、贷款、信用卡等)

5.4 CocoaPods本地库(本地库+Demo工程)

pod spec create指令

咱们前面创立本地库的方法是经过:

  • 创立一个文件夹
  • 在文件夹内部放置库代码
  • 经过pod spec create指令给pod库生成描绘文件,并依据当时文件夹寄存资源的途径修正.podspec

但这种编写pod库的方法,是没有附带Demo工程的且没有单元测验

pod lib create指令

咱们还有 另一个 pod 指令:pod lib create 能够用于创立Pod库,该创立方法能够趁便创立Demo工程和单元测验::

    pod lib create XXXXX(你的库名)

03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

  • 示例:
    ❯ pod lib create NKTestPodLib
    Cloning `https://github.com/CocoaPods/pod-template.git` into `NKTestPodLib`.
    Configuring NKTestPodLib template.
    security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
    ------------------------------
    To get you started we need to ask a few questions, this should only take a minute.
    If this is your first time we recommend running through with the guide:
     - https://guides.cocoapods.org/making/using-pod-lib-create.html
     ( hold cmd and click links to open in a browser. )
    What platform do you want to use?? [ iOS / macOS ]
     > iOS
    What language do you want to use?? [ Swift / ObjC ]
     > ObjC
    Would you like to include a demo application with your library? [ Yes / No ]
     > Yes
    Which testing frameworks will you use? [ Specta / Kiwi / None ]
     > None
    Would you like to do view based testing? [ Yes / No ]
     > No
    What is your class prefix?
     > NK
    security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
    security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
    security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
    security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
    security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
    security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
    hint: Using 'master' as the name for the initial branch. This default branch name
    hint: is subject to change. To configure the initial branch name to use in all
    hint: of your new repositories, which will suppress this warning, call:
    hint:
    hint: 	git config --global init.defaultBranch <name>
    hint:
    hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
    hint: 'development'. The just-created branch can be renamed via this command:
    hint:
    hint: 	git branch -m <name>
    Running pod install on your new library.
    Analyzing dependencies
    Downloading dependencies
    Installing NKTestPodLib (0.1.0)
    Generating Pods project
    Integrating client project
    [!] Please close any current Xcode sessions and use `NKTestPodLib.xcworkspace` for this project from now on.
    Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
     Ace! you're ready to go!
     We will start you off by opening your project in Xcode
      open 'NKTestPodLib/Example/NKTestPodLib.xcworkspace'
    To learn more about the template see `https://github.com/CocoaPods/pod-template.git`.
    To learn more about creating a new pod, see `https://guides.cocoapods.org/making/making-a-cocoapod`.
    

pod lib create指令 + 自界说 Pod库模板

咱们 前面经过 pod lib create指令 创立 Pod库,它默许会去依据 Cocoapods官方的Pod库模板进行创立。且这需求不断发问许多个小问题,这过程许多显得流程相对繁琐;

为了直接一步到位,咱们能够依据自界说 Pod库模板,并按照相应的创立方法,一条指令创立pod库:
此处运用的是我个人的 Pod库模板 pod-template

  • Swift Pod 库:
     pod lib create Pod库称号 Swift --template-url="https://github.com/VanZhang-CN-SZ-SN9037/pod-template"
    
  • OC Pod 库:
     pod lib create Pod库称号 Objc --template-url="https://github.com/VanZhang-CN-SZ-SN9037/pod-template"
    

5.5 CocoaPods 长途库

私有库长途库公有库长途库

当咱们把本地库开发好一个版别之后,若咱们想要为外部供给一个Pod库,咱们则需求把本地库上传到git云服务器:

  • 公有库: 若是想将开发好的本地Pod库发布出去,供给一个挑选给广大开发者,咱们需求再开源社区Git,创立一个 代码库房,一般挑选 github
  • 私有库: 若是刚开发好的本地Pod库 仅在 作为 公司 移动开发套件的一部分,在公司内部团队发布,则 需求 在公司布置了Git服务的私有云,创立一个 代码库房,用于保存
  • 无论是 公有库 还是 私有库, 他们 除了存储的 git库房 地址不同,还有几点不同:
    • .podspec文件存储不同:
      • 公有库推送到Cocoapods的Podspec
      • 私有库需求在私有云的git另建一个库房,用于存储私有Pod库的Podspec文件(多个库的Pocspec文件能够存储到同一个Podspec仓里边,其Pod库代码各占一个git仓)

生成一个本地库很简单,可是本地库在办理和运用上有必定的局限性,例如:

  • 需求在 Podfile 文件中主动指明途径;
  • 版别晋级不简单保护;
  • 多人开发时,不便利进行协作;

长途库就能够便利的解决以上的问题,制造长途私有库分为以下几个过程:

  1. 创立 Git 长途库房;
    • 长途库(私有库):
      • 在git云渠道,创立私有代码仓,用于存储Pod库;/在私有云 git 渠道中创立代码仓,用于存储Pod库;
    • 长途库(公有库):
      • 在公有云git渠道,创立公有代码仓,用于存储Pod库;
  2. 创立 Pod 所需求的项目工程文件,并上传到 Git 代码仓;
  3. 验证 podspec 描绘文件;
  4. 提交 podspec 描绘文件;
    • 长途库(私有库): 提交到 Cocoapods 官方的 Spec存储代码仓
    • 长途库(公有库): 提交到 个人 创立的 专门存储 私有库 描绘文件 Spec的私有仓
  5. 运用 Pod 库;

5.6 CocoaPods 长途库(公有库)

创立公有库长途库

依据前面的过程,现在你需求将生成的 NKTestLib.podspec 文件上传到长途索引库,在此之前,你需求注册一个 Trunk 账号,文档如下: guides.cocoapods.org/making/gett…

注册 Trunk 账号

现在履行下面的指令,记住修正邮箱昵称描绘等:

  • pod trunk register 邮箱地址 ‘称号’ --description=‘MacBook’
    pod trunk register toBeABetterManZxh91@gmail.com 'VanZhang' --description='Macbook Pro'
    
  • 打印[!] Please verify the session by clicking the link in the verification email that has been sent to toBeABetterManZxh91@gmail.com意味着 邮件发送成功,要去邮箱查看
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 点击邮箱里的承认链接,你才算真实注册 Trunk 账号成功
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

查看 xxx.podspec的合法性

打开邮件里边的链接后,会有相似 you can back to your termainal 的提示,意味着咱们能够进行下一步了:

  • cd 到 xxx.podspec 同一目录下
  • pod lib lint 查看 xxx.podspec 的合法性
    pod lib lint --allow-warnings
    
    • 若报错,依据过错提示修复问题
    • 当显现 passed validation 后,说明 xxx.podspec合法,则咱们需求把咱们本地的xxx.podspec 推送到 Cocoapods存储Specs文件的库
      03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

把 合法的 xxx.podspec 推送到 Cocoapods存储Specs文件的库

  • pod trunk push 推送 xxx.podspec 推送到 Cocoapods存储Specs文件的库

    pod trunk push NKTestLib.podspec
    
  • 推送成功的标识: 提示信息如下:

    Validating podspec
     -> NKTestLib (0.1.0)
    - WARN  | source: Git SSH URLs will NOT work for people behind firewalls configured to only allow HTTP, therefore HTTPS is preferred.
    - WARN  | description: The description is shorter than the summary.
    - NOTE  | [NKTestLib/CommerceUI] xcodebuild:  note: Using codesigning identity override: -
    - NOTE  | [NKTestLib/CommerceUI] xcodebuild:  note: Building targets in dependency order
    - NOTE  | [iOS] xcodebuild:  NKTestLib/Assets/NKTempViewController.xib:WGN-9d-qT2: warning: Filled Button Style before iOS 15.0 [5]
    Updating spec repo `trunk`
    --------------------------------------------------------------------------------
       Congrats
       NKTestLib (0.1.0) successfully published
       March 14th, 03:05
       https://cocoapods.org/pods/NKTestLib
       Tell your friends!
    --------------------------------------------------------------------------------
    

    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

  • 审核
    此时你的 xxx.podspec 就会 pull request 到长途索引库,CocoaPods 官方审核经往后,就能够出现在长途索引库中,当长途索引库录入后:

    pod setup
    
  • 删去本地索引文件
    这时你的本地索引库,会新加入 你的xxx.podspec 这条记载,可是本地索引文件还未更新,因而删去掉以下途径的本地索引文件:

    ~/Library/Caches/CocoaPods/search_index.json
    
  • pod search
    履行 pod search NKTestLib 指令,当 search_index.json 文件重建结束后,就能够在运用这个长途结构库了。

  • pod install --repo-update 导入公有云的库

    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

5.7 CocoaPods 长途库(私有库)

创立公有库长途库

长途私有库作业流程
03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

5.7.1 SSH 授权

此次创立私有库,我运用的git渠道是 码云
添加私有索引库需求运用 SSH 授权,也是和 Git 库房相同的,了解的同学能够跳过这一过程,首先创立公钥:

ssh-keygen

然后找到下面的文件:

~/.ssh/id_rsa.pub

里边寄存的字符便是公钥了,然后将公钥添加码市,链接如下:

https://gitee.com/profile/sshkeys

5.7.2 添加私有长途索引库

  • 添加 pod repo库 用于存储私有库的 Spec文件:
  • 履行 pod repo,能够看到当前本地的repo库个数和相关的信息下面的信息:
    ## 输入终端指令:
    pod repo
    ## 打印:
    brightcove-brightcovespecs
    - Type: git (master)
    - URL:  https://github.com/brightcove/BrightcoveSpecs.git
    - Path: /Users/VZha33/.cocoapods/repos/brightcove-brightcovespecs
    nike-internal-mpe.tool.specs
    - Type: git (main)
    - URL:  git@github.com:nike-internal/mpe.tool.specs.git
    - Path: /Users/VZha33/.cocoapods/repos/nike-internal-mpe.tool.specs
    trunk
    - Type: CDN
    - URL:  https://cdn.cocoapods.org/
    - Path: /Users/VZha33/.cocoapods/repos/trunk
    
  • 履行 pod repo add 添加 存储咱们私有库的 Specsrepo
        ## 语法:
        ## pod repo add 期望保存在本地的Repo称号 Pod私有库存储Specs的Repo git地址(一般直接用ssh授权的地址)
        ## 示例:
        pod repo add NKMobilePaaSSpecs git@gitee.com:LuckyVan_admin/nkmobile-paa-sspecs.git
    
  • 再次履行 pod repo,查看:
      ## 输入终端指令:
      pod repo
      ## 打印:
      brightcove-brightcovespecs
      - Type: git (master)
      - URL:  https://github.com/brightcove/BrightcoveSpecs.git
      - Path: /Users/VZha33/.cocoapods/repos/brightcove-brightcovespecs
      nike-internal-mpe.tool.specs
      - Type: git (main)
      - URL:  git@github.com:nike-internal/mpe.tool.specs.git
      - Path: /Users/VZha33/.cocoapods/repos/nike-internal-mpe.tool.specs
      NKMobilePaaSSpecs
      - Type: git (master)
      - URL:  git@gitee.com:LuckyVan_admin/nkmobile-paa-sspecs.git
      - Path: /Users/VZha33/.cocoapods/repos/NKMobilePaaSSpecs
      trunk
      - Type: CDN
      - URL:  https://cdn.cocoapods.org/
      - Path: /Users/VZha33/.cocoapods/repos/trunk
      4 repos
    
    此时咱们的 CocoaPods 长途索引库就装置好了。咱们也能够到下面的途径去看一下:
    ~/.cocoapods/repos
    
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

5.7.3 上传源码到 Git

为了快速完结实践,咱们直接把前面创立的本地库,修正一下称号和装备,上传到私有git仓,进行实践:

  • 修正文件夹称号(NKTestLib->NKTestLibPrivacyLib)
  • 修正podspec称号(NKTestLib->NKTestLibPrivacyLib)
  • 修正podspec装备
    • 称号:NKTestLib->NKTestLibPrivacyLib
    • git库房地址:换位私有git仓地址
    • 其他保存原样
  • 修正后的podspec:
#
#  Be sure to run `pod spec lint NKTestLib.podspec' to ensure this is a
#  valid spec and to remove all comments including this before submitting the spec.
#
#  To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html
#  To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
#
Pod::Spec.new do |spec|

  # ―――  Spec Metadata  ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  These will help people to find your library, and whilst it
  #  can feel like a chore to fill in it's definitely to your advantage. The
  #  summary should be tweet-length, and the description more in depth.
  #
  spec.name         = "NKTestLibPrivacyLib"
  spec.version      = "0.1.0"
  spec.summary      = "This is a Pod Lib Demo for blog."

  # 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!
  spec.description  = "一般描绘库的用处、主要功用等"
  spec.homepage     = "https://github.com/VanZhang-CN-SZ-SN9037/NKTestLib"
  # spec.screenshots  = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"

  # ―――  Spec License  ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Licensing your code is important. See https://choosealicense.com for more info.
  #  CocoaPods will detect a license file if there is a named LICENSE*
  #  Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
  #
  spec.license      = { :type => "MIT", :file => "./LICENSE" }

  # ――― Author Metadata  ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Specify the authors of the library, with email addresses. Email addresses
  #  of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
  #  accepts just a name if you'd rather not provide an email address.
  #
  #  Specify a social_media_url where others can refer to, for example a twitter
  #  profile URL.
  #
  spec.author             = { "Van Zhang" => "toBeABetterManZxh91@gmail.com" }
  # Or just: spec.author    = "Van Zhang"
  # spec.authors            = { "Van Zhang" => "Van.Zhang@nike.com" }
  # spec.social_media_url   = "https://twitter.com/Van Zhang"

  # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  If this Pod runs only on iOS or OS X, then specify the platform and
  #  the deployment target. You can optionally include the target after the platform.
  #
   spec.platform     = :ios, "14.0"
  # spec.platform     = :ios, "5.0"

  #  When using multiple platforms
  spec.ios.deployment_target = "14.0"
  # spec.osx.deployment_target = "10.7"
  # spec.watchos.deployment_target = "2.0"
  # spec.tvos.deployment_target = "9.0"
  spec.swift_version = "5.4"

  # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Specify the location from where the source should be retrieved.
  #  Supports git, hg, bzr, svn and HTTP.
  #
  spec.source       = { :git => "git@gitee.com:LuckyVan_admin/nktest-lib-privacy-lib.git", :tag => "#{spec.version}" }

  # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  CocoaPods is smart about how it includes source code. For source files
  #  giving a folder will include any swift, h, m, mm, c & cpp files.
  #  For header files it will include any header in the folder.
  #  Not including the public_header_files will make all headers public.
  #
  #spec.source_files  = "Classes", ".//Classes/*.{c,h,m,mm,swift}"
  #spec.exclude_files = "Classes/Exclude"
  spec.prefix_header_contents = '#import <UIKit/UIKit.h>'

  # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  A list of resources included with the Pod. These are copied into the
  #  target bundle with a build phase script. Anything else will be cleaned.
  #  You can preserve files from being cleaned, please don't preserve
  #  non-essential files like tests, examples and documentation.
  #
  # spec.resource  = "icon.png"
  # spec.resources = "Sources/Assets/*"

  # spec.preserve_paths = "FilesToSave", "MoreFilesToSave"

  # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  Link your library with frameworks, or libraries. Libraries do not include
  #  the lib prefix of their name.
  #
  # spec.framework  = "SomeFramework"
  spec.frameworks = ['CoreTelephony','CoreFoundation','AdSupport','AppTrackingTransparency']

  # spec.library   = "iconv"
  spec.libraries = ['c++', 'resolv.9']

  # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
  #
  #  If your library depends on compiler flags you can set them in the xcconfig hash
  #  where they will only apply to your library. If you depend on other Podspecs
  #  you can include multiple dependencies to ensure it works.

  # spec.requires_arc = true

  # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
  spec.static_framework = true 
  #spec.vendored_frameworks = 'Sources/Classes/Vendor/AliTigerTally_IDFA.xcframework'
  #spec.dependency "Alamofire", "~>5"

  # ――― Sub Spec Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #  
  spec.subspec 'CommerceUI' do |c|
    c.source_files = 'Sources/Classes/CommerceUI/**/*'
  end
end
  • 运用 pod lib create + 模板url,快速创立一个带 集成Demo的模板工程
        pod lib create NKTestLibPrivacyLib Swift --template-url="https://github.com/VanZhang-CN-SZ-SN9037/pod-template"
    
  • 源码拖到 Sources/Classes 的目录:
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 图片的资源文件拖到 Sources/Assets 的目录:
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 创立私有git仓:
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 提交git日志,打tag,上传代码(留意Tag的版别号,要和Podspec里边的版别号保持一致)
    git tag '0.1.0'
    git push --tags
    

5.7.4 上传 Spec 到长途索引库

检验经往后,提示如下:

03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

  • podspec 文件推到前面创立的长途私有索引库(NKMobilePaaSSpecs):
    pod repo push NKMobilePaaSSpecs NKTestLibPrivacyLib.podspec --allow-warnings
    
  • 推送成功的标志:
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 更新本地的 NKMobilePaaSSpecsrepo
        pod repo update NKMobilePaaSSpecs
    
  • 更新成功后,修正Podfile文件
# Uncomment the next line to define a global platform for your project
source "git@gitee.com:LuckyVan_admin/nkmobile-paa-sspecs.git"
platform :ios, '14.0'
target 'NKTestLibPrivacyLib' do

#  pod 'NKTestLibPrivacyLib', :path => '/Users/VZha33/GitHub/Temp/NKTestLibPrivacyLib/NKTestLibPrivacyLib.podspec',:subspecs => ['CommerceUI']
 pod 'NKTestLibPrivacyLib'
end
  • 履行 pod install,整个长途私有库的树立和运用就完结了
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 咱们前面在创立本地库的时分,独自装备库与库的资源文件信息,也能够把库集成到其它工程中进行运用:
  • 咱们此次在创立长途库的时分,运用了Cocoapods办理+个人Pod库模板+私有git仓的形式。这样做的好处:
    • 运用Cocoapods的模板库创立形式,一起创立了一个库文件包+Example工程,
      • 独自测验:能够对本库独自集成,进行功用测验、单元测验
    • 运用了个人Pod库模板而不是官方模板,避免了繁琐的创立流程
      • 运用官方模板的创立指令:
        pod lib create XXX你的库名
        ////////////////////////////////////////////////////////////////////////
        What language do you want to use?? [ Swift / ObjC ] 
         > Swift
        Would you like to include a demo application with your library? [ Yes / No ]
         > Yes
        Which testing frameworks will you use? [ Quick / None ]
         > None
        Would you like to do view based testing? [ Yes / No ]
         > Yes
        
      • 运用个人模板的创立指令:
        OC库工程: pod lib create XXX你的库名 Objc --template-url="https://github.com/VanZhang-CN-SZ-SN9037/pod-template"
        Swift库工程:pod lib create XXX你的库名 Swift --template-url="https://github.com/VanZhang-CN-SZ-SN9037/pod-template"
        

5.8 Pod库的其它办理

5.8.1 Pods库 迭代晋级

咱们在树立公司的移动开发套件的时分,随着事务的丰厚以及项目功用版别的迭代,总会有对组件晋级的时分。

咱们现在来测验一下,Cocoapods组件库晋级的办理:
现在咱们沿着前面的测验例子,给 NKTestLibPrivacyLib 进行晋级,给它再添加一些功用:

  • 晋级前的podspec(subspec只有CommerceUI一个子仓):
    #
    #  Be sure to run `pod spec lint NKTestLib.podspec' to ensure this is a
    #  valid spec and to remove all comments including this before submitting the spec.
    #
    #  To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html
    #  To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
    #
    Pod::Spec.new do |spec|
    
      # ―――  Spec Metadata  ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      #  These will help people to find your library, and whilst it
      #  can feel like a chore to fill in it's definitely to your advantage. The
      #  summary should be tweet-length, and the description more in depth.
      #
      spec.name         = "NKTestLibPrivacyLib"
      spec.version      = "0.1.0"
      spec.summary      = "This is a Pod Lib Demo for blog."
    
      # 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!
      spec.description  = "一般描绘库的用处、主要功用等"
      spec.homepage     = "https://github.com/VanZhang-CN-SZ-SN9037/NKTestLib"
      # spec.screenshots  = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
    
      # ―――  Spec License  ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      #  Licensing your code is important. See https://choosealicense.com for more info.
      #  CocoaPods will detect a license file if there is a named LICENSE*
      #  Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
      #
      spec.license      = { :type => "MIT", :file => "./LICENSE" }
    
      # ――― Author Metadata  ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      #  Specify the authors of the library, with email addresses. Email addresses
      #  of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
      #  accepts just a name if you'd rather not provide an email address.
      #
      #  Specify a social_media_url where others can refer to, for example a twitter
      #  profile URL.
      #
      spec.author             = { "Van Zhang" => "toBeABetterManZxh91@gmail.com" }
      # Or just: spec.author    = "Van Zhang"
      # spec.authors            = { "Van Zhang" => "Van.Zhang@nike.com" }
      # spec.social_media_url   = "https://twitter.com/Van Zhang"
    
      # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      #  If this Pod runs only on iOS or OS X, then specify the platform and
      #  the deployment target. You can optionally include the target after the platform.
      #
       spec.platform     = :ios, "14.0"
      # spec.platform     = :ios, "5.0"
    
      #  When using multiple platforms
      spec.ios.deployment_target = "14.0"
      # spec.osx.deployment_target = "10.7"
      # spec.watchos.deployment_target = "2.0"
      # spec.tvos.deployment_target = "9.0"
      spec.swift_version = "5.4"
    
      # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      #  Specify the location from where the source should be retrieved.
      #  Supports git, hg, bzr, svn and HTTP.
      #
      spec.source       = { :git => "git@gitee.com:LuckyVan_admin/nktest-lib-privacy-lib.git", :tag => "#{spec.version}" }
    
      # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      #  CocoaPods is smart about how it includes source code. For source files
      #  giving a folder will include any swift, h, m, mm, c & cpp files.
      #  For header files it will include any header in the folder.
      #  Not including the public_header_files will make all headers public.
      #
      #spec.source_files  = "Classes", ".//Classes/*.{c,h,m,mm,swift}"
      #spec.exclude_files = "Classes/Exclude"
      spec.prefix_header_contents = '#import <UIKit/UIKit.h>'
    
      # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      #  A list of resources included with the Pod. These are copied into the
      #  target bundle with a build phase script. Anything else will be cleaned.
      #  You can preserve files from being cleaned, please don't preserve
      #  non-essential files like tests, examples and documentation.
      #
      # spec.resource  = "icon.png"
      # spec.resources = "Sources/Assets/*"
    
      # spec.preserve_paths = "FilesToSave", "MoreFilesToSave"
    
      # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      #  Link your library with frameworks, or libraries. Libraries do not include
      #  the lib prefix of their name.
      #
      # spec.framework  = "SomeFramework"
      spec.frameworks = ['CoreTelephony','CoreFoundation','AdSupport','AppTrackingTransparency']
    
      # spec.library   = "iconv"
      spec.libraries = ['c++', 'resolv.9']
    
      # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      #  If your library depends on compiler flags you can set them in the xcconfig hash
      #  where they will only apply to your library. If you depend on other Podspecs
      #  you can include multiple dependencies to ensure it works.
    
      # spec.requires_arc = true
    
      # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
      spec.static_framework = true 
      #spec.vendored_frameworks = 'Sources/Classes/Vendor/AliTigerTally_IDFA.xcframework'
      #spec.dependency "Alamofire", "~>5"
    
      # ――― Sub Spec Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      spec.subspec 'CommerceUI' do |c|
        c.source_files = 'Sources/Classes/CommerceUI/**/*'
      end
    end
    
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 晋级后的podspec(subspec加了Extension一个子仓):
    #
    # Be sure to run `pod spec lint NKTestLib.podspec' to ensure this is a
    # valid spec and to remove all comments including this before submitting the spec.
    #
    # To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html
    # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
    #
    Pod::Spec.new do |spec|
      # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      # These will help people to find your library, and whilst it
      # can feel like a chore to fill in it's definitely to your advantage. The
      # summary should be tweet-length, and the description more in depth.
      #
      spec.name     = "NKTestLibPrivacyLib"
      spec.version   = "0.1.0"
      spec.summary   = "This is a Pod Lib Demo for blog."
    
      # 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!
      spec.description = "一般描绘库的用处、主要功用等"
      spec.homepage   = "https://github.com/VanZhang-CN-SZ-SN9037/NKTestLib"
      # spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
    
      # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      # Licensing your code is important. See https://choosealicense.com for more info.
      # CocoaPods will detect a license file if there is a named LICENSE*
      # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
      #
      spec.license   = { :type => "MIT", :file => "./LICENSE" }
      # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      # Specify the authors of the library, with email addresses. Email addresses
      # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
      # accepts just a name if you'd rather not provide an email address.
      #
      # Specify a social_media_url where others can refer to, for example a twitter
      # profile URL.
      #
      spec.author       = { "Van Zhang" => "toBeABetterManZxh91@gmail.com" }
      # Or just: spec.author  = "Van Zhang"
      # spec.authors      = { "Van Zhang" => "Van.Zhang@nike.com" }
      # spec.social_media_url  = "https://twitter.com/Van Zhang"
      # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      # If this Pod runs only on iOS or OS X, then specify the platform and
      # the deployment target. You can optionally include the target after the platform.
      #
       spec.platform   = :ios, "14.0"
      # spec.platform   = :ios, "5.0"
      # When using multiple platforms
      spec.ios.deployment_target = "14.0"
      # spec.osx.deployment_target = "10.7"
      # spec.watchos.deployment_target = "2.0"
      # spec.tvos.deployment_target = "9.0"
      spec.swift_version = "5.4"
      # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      # Specify the location from where the source should be retrieved.
      # Supports git, hg, bzr, svn and HTTP.
      #
      spec.source    = { :git => "git@gitee.com:LuckyVan_admin/nktest-lib-privacy-lib.git", :tag => "#{spec.version}" }
    
      # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      # CocoaPods is smart about how it includes source code. For source files
      # giving a folder will include any swift, h, m, mm, c & cpp files.
      # For header files it will include any header in the folder.
      # Not including the public_header_files will make all headers public.
      #
      #spec.source_files = "Classes", ".//Classes/*.{c,h,m,mm,swift}"
      #spec.exclude_files = "Classes/Exclude"
      spec.prefix_header_contents = '#import <UIKit/UIKit.h>'
      # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      # A list of resources included with the Pod. These are copied into the
      # target bundle with a build phase script. Anything else will be cleaned.
      # You can preserve files from being cleaned, please don't preserve
      # non-essential files like tests, examples and documentation.
      #
      # spec.resource = "icon.png"
      # spec.resources = "Sources/Assets/*"
      # spec.preserve_paths = "FilesToSave", "MoreFilesToSave"
    
      # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      # Link your library with frameworks, or libraries. Libraries do not include
      # the lib prefix of their name.
      #
      # spec.framework = "SomeFramework"
      spec.frameworks = ['CoreTelephony','CoreFoundation','AdSupport','AppTrackingTransparency']
      # spec.library  = "iconv"
      spec.libraries = ['c++', 'resolv.9']
    
      # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
      #
      # If your library depends on compiler flags you can set them in the xcconfig hash
      # where they will only apply to your library. If you depend on other Podspecs
      # you can include multiple dependencies to ensure it works.
      # spec.requires_arc = true
      # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
      spec.static_framework = true
      #spec.vendored_frameworks = 'Sources/Classes/Vendor/AliTigerTally_IDFA.xcframework'
    
      #spec.dependency "Alamofire", "~>5"
      # ――― Sub Spec Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
        spec.subspec 'Extension' do |e|
           e.source_files = 'Sources/Classes/Extension/**/*'
        end
      spec.subspec 'CommerceUI' do |c|
        c.source_files = 'Sources/Classes/CommerceUI/**/*'
      end 
    end
    
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 查看一下私有库spec是否有过错:
    pod lib lint --allow-warnings
    
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 查看经往后,修正podspec中的库版别号为0.2.0,提交本地git日志,打就能够将 NKTestLibPrivacyLib0.2.0 版别推到长途私有库中,一起树立 0.2.0 的 Tag
  • 推送新版别的podspec到私有库Spec文件的存储仓NKMobilePaaSSpecs 查看经往后,履行:
    pod repo push NKMobilePaaSSpecs NKTestLibPrivacyLib.podspec --allow-warnings
    
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 更新本地的 NKMobilePaaSSpecs
    pod repo update NKMobilePaaSSpecs
    
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 重新 在 工程中 pod install, 集成新版别的 NKTestLibPrivacyLib:
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

5.8.2 Pod库 资源办理

咱们在 创立 pod库的时分留意设置好资源文件途径的办理规则,再加载Pod库的资源存储的bundle途径+文件称号即可正常加载资源。
现在来演示一遍:

  • 查看.podspec对资源文件办理的设置:
    ## 选用 resource_bundles 字段办理,会默许给pod库发明一个指定称号的bundle文件,将指定的资源悉数存储在bundle里边,在集成工程完结Build的时分,会把该bundle存储在集成工程内部
    ## 此处 案例中 NKTestLibPrivacyLibResources 为 bundle的称号
    ## => 只想的括号内部,分别是资源文件在本来的Pod库中的存储途径
    spec.resource_bundles  = {
         'NKTestLibPrivacyLibResources' => ['Sources/Classes/**/*.xib', 'Sources/Assets/*']
    }
    
  • command+B,build一下项目,找到工程内部的Product文件夹,show in finder,查看一下生成的bundle的结果:
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 我写了一个Extension帮助咱们快速获取资源文件的途径,仅供参考:
    • NSBundle+BundlePath.h
      //
      // NSString+BundlePath.h
      // NKTestLibPrivacyLib
      //
      // Created by Van Zhang on 2023/3/16.
      //
      #import <Foundation/Foundation.h>
      NS_ASSUME_NONNULL_BEGIN
      @interface NSBundle (BundlePath)
      + (NSBundle*)currentLibraryBundle;
      + (NSBundle*)resourceBundleWith:(NSString*)bundleName;
      + (NSString*)pathWithBundleName:(NSString*)bundle;
      @end
      NS_ASSUME_NONNULL_END
      
    • NSBundle+BundlePath.m (Tips:大家若是要运用,记住针对你当时的pod库修正currentLibraryBundle内部的bundle称号(把前面.podspecspec.resource_bundles字段的bundle称号拷过来即可)
      //
      // NSBundle+BundlePath.m
      // NKTestLibPrivacyLib
      //
      // Created by Van Zhang on 2023/3/16.
      //
      #import "NSBundle+BundlePath.h"
      @implementation NSBundle (BundlePath)
      static NSBundle *resourceBundle = nil;
      static dispatch_once_t onceToken;
      + (NSBundle*)currentLibraryBundle{
          dispatch_once(&onceToken, ^{
              resourceBundle = [NSBundle resourceBundleWith:@"NKTestLibPrivacyLibResources"];
          });
          return resourceBundle;
      }  
      + (NSString *)pathWithBundleName:(NSString *)bundle{
          NSString *bundleName = [self checkBundleNamePathExtension:bundle];
          NSString *bundlePath = nil;
          for (bundle in [NSBundle allBundles]) {
              if ([[(NSBundle*)bundle bundlePath].lastPathComponent isEqualToString:bundleName]){
                  bundlePath = [(NSBundle*)bundle bundlePath];
                  break
              }
          }
          return bundlePath;
      }
      + (NSBundle*)resourceBundleWith:(NSString*)bundleName{
          return [NSBundle bundleWithPath:[NSBundle pathWithBundleName:bundleName]];
      }
      + (NSString*)checkBundleNamePathExtension:(NSString*)bundleName{
          NSString *bundlePathExtension = @"bundle";
          return [bundleName stringByAppendingPathExtension:[bundleName.pathExtension isEqualToString:@"bundle"]?@"":bundlePathExtension];
      }
      @end
      
    • 咱们 修正一下 工程 加载资源的 代码:
      • pod 库内部 的代码加载资源:
        03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
        NSString *filePath = [[NSBundle currentLibraryBundle] pathForResource:@"images/0" ofType:@"jpg"];
        UIImage *img = [UIImage imageWithContentsOfFile:filePath];
        
      • 集成pod库的项目内部 的代码加载资源:
        03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
        let topBundlePath = Bundle.main.path(forResource: "NKTestLibPrivacyLibResources", ofType: "bundle")
        guard let nibBundlePath = topBundlePath else {
            return
        }
        let topBundle = Bundle(path: nibBundlePath)
        let tempVc = NKTempViewController(nibName: "NKTempViewController", bundle: topBundle)
        self.present(tempVc, animated: true) {
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3, execute: DispatchWorkItem(block: {
                tempVc.dismiss(animated: true)
            }))
        }
        // print((UIImage(contentsOfBundleName: "NKTestLibPrivacyLib", file: "images/0.jpg")) ?? "没有图片")
        print("bundlePath:\(Bundle.currentLibrary())")
        
    • run 一下工程 查看一下 加载 作用:
      03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
      03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
      03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
      03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

至此,当时针对Cocoapods的资源办理调整与实践根本完结

5.9 Podfile文件的优化

咱们能够在Podfile中加入这一段代码:

install! 'cocoapods',
   :deterministic_uuids => false,
   :lock_pod_sources => false,
   :disable_input_output_paths => true,
   :generate_multiple_pod_projects => true,
   :preserve_pod_file_structure => true
inhibit_all_warnings!
post_install do | installer |
   installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      puts target.name
    end
   end
  aggregate_target = installer.aggregate_targets[0]
  aggregate_build_settings_by_config = aggregate_target.xcconfigs.collect { |k, v| [k, v.to_hash] }.to_h
  puts aggregate_build_settings_by_config
  installer.pod_target_subprojects.each do |pod_subproject|
   pod_subproject.native_targets.each do |pod_native_target|
    puts pod_native_target
    pod_native_target.build_configurations.each do |build_configuration|
             aggregate_build_settings = aggregate_build_settings_by_config[build_configuration.name]
             build_configuration.build_settings['HEADER_SEARCH_PATHS'] = "${PODS_ROOT}/Headers/Public"
             build_configuration.build_settings['FRAMEWORK_SEARCH_PATHS'] = aggregate_build_settings['FRAMEWORK_SEARCH_PATHS']
             build_configuration.build_settings['LIBRARY_SEARCH_PATHS'] = aggregate_build_settings['LIBRARY_SEARCH_PATHS']
    end
   end
  end
end

这段代码的功用是把每一个pod库在导入的时分,都编译成一个静态库Framework,在打包项目包体积的一起,还能够恰当提高平时开发的编译速度。

  • 添加之前的Podfile
    # Uncomment the next line to define a global platform for your project
    source "git@gitee.com:LuckyVan_admin/nkmobile-paa-sspecs.git"
    #use_frameworks! :linkage => :static
    #use_modular_headers!
    platform :ios, '14.0'
    target 'NKTestLibPrivacyLib-Example' do
        pod 'NKTestLibPrivacyLib', :path => '/Users/VZha33/GitHub/Temp/NKTestLibPrivacyLib/NKTestLibPrivacyLib.podspec'
    #  ,:subspecs => ['CommerceUI']
    #  pod 'NKTestLibPrivacyLib'
    end
    
  • 添加之后的Podfile
       # Uncomment the next line to define a global platform for your project
       source "git@gitee.com:LuckyVan_admin/nkmobile-paa-sspecs.git"
       #use_frameworks! :linkage => :static
       #use_modular_headers!
       platform :ios, '14.0'
       install! 'cocoapods',
             :deterministic_uuids => false,
             :lock_pod_sources => false,
             :disable_input_output_paths => true,
             :generate_multiple_pod_projects => true,
             :preserve_pod_file_structure => true
       inhibit_all_warnings!
       post_install do | installer |
             installer.pods_project.targets.each do |target|
                target.build_configurations.each do |config|
                   puts target.name
                end
             end
            aggregate_target = installer.aggregate_targets[0]
            aggregate_build_settings_by_config = aggregate_target.xcconfigs.collect { |k, v| [k, v.to_hash] }.to_h
            puts aggregate_build_settings_by_config
            installer.pod_target_subprojects.each do |pod_subproject|
              pod_subproject.native_targets.each do |pod_native_target|
                puts pod_native_target
                pod_native_target.build_configurations.each do |build_configuration|
                    aggregate_build_settings = aggregate_build_settings_by_config[build_configuration.name]
                    build_configuration.build_settings['HEADER_SEARCH_PATHS'] = "${PODS_ROOT}/Headers/Public"
                    build_configuration.build_settings['FRAMEWORK_SEARCH_PATHS'] = aggregate_build_settings['FRAMEWORK_SEARCH_PATHS']
                    build_configuration.build_settings['LIBRARY_SEARCH_PATHS'] = aggregate_build_settings['LIBRARY_SEARCH_PATHS']
                end
              end
            end
       end
       target 'NKTestLibPrivacyLib-Example' do
           pod 'NKTestLibPrivacyLib', :path => '/Users/VZha33/GitHub/Temp/NKTestLibPrivacyLib/NKTestLibPrivacyLib.podspec'
       #  ,:subspecs => ['CommerceUI']
       #  pod 'NKTestLibPrivacyLib'
       end
    
  • 添加之前的工程目录
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等
  • 添加之后的工程目录
    03-iOS架构设计|模块化、组件化-依赖包管理工具Cocoapods常用实践:组件库(本地库、远程库(公有、私有))创建、模板工程、划分、资源管理、优化等

私有库实践工程的链接:github.com/VanZhang-CN…

总结

咱们本次在本篇文章顺次介绍了依靠包办理东西的:

  • 发明背景和用处
  • Pod库的分类:本地库、主库+子库、长途公有库、长途私有库
  • Pod库的创立和相关的资源办理:.podspec的装备、pod库资源办理、pod长途库发布和Pod库晋级

本次并未拓宽评论的论题

  • 深入评论 pod库个人模板工程的定制 以及 相关 脚本文件的书写
  • Cocoapods 插件开发
  • Cocoapods + Fastlane + Jenkins 完结iOS工程的继续集成
  • Cocoapods 底层原理
  • 引荐的Cocoapods优质开源库
    • 若是你毫无思路,欢迎阅览我的这篇文章(树立自己的iOS常识系统),先了解一下iOS开发的过程中,各个阶段需求重视什么,然后挑选那些三方库/朝着哪些方向去制造自己的Pod库以完结自己公司内部的iOS移动开发套件

若咱们要进一步对未评论的子论题发掘,咱们则需求把握更多的前常识。
比方,pod库个人模板工程的定制 以及 相关 脚本文件的书写、Cocoapods 插件开发、Cocoapods + Fastlane + Jenkins 完结iOS工程的继续集成、Cocoapods 底层原理等论题。则要求咱们需求把握必定的脚本语言Ruby、Fastlane、Gem、Homebrew、Jenkins等
若是你有爱好,也能够和我共享你的探究经历。欢迎Q我,让咱们彼此借鉴,共同进步!!! ……

相关阅览

  • Cocoapods官网

专题系列文章

iOS架构规划

  • 1.iOS架构规划|总述
  • 2.iOS架构规划|iOS模块化开发(待输出)
  • 3.iOS架构规划|iOS组件化开发-依靠包办理东西Cocoapods常用实践:组件库(本地库、长途库(公有、私有))创立、模板工程、区分、资源办理、优化等
  • 4.iOS架构规划|iOS组件化开发【组件办理、组件分类、组件区分、组件开发】(待输出)
  • 5.iOS架构规划|iOS开发包二进制化【.a静态库、.framework(静态库、动态库)、.dyld动态库、.xcfameworks等】

探究iOS底层原理

  • 探究iOS底层原理|总述