iOS | 给项目添加pods支持

目录

1、创建远程库

2、提交项目代码并打好tag标签

3、创建并编辑.podspec索引文件

4、把.podspec提交到Cocoapods trunk

5、可能会遇到的问题

6、组件库与私有化

1、创建远程库

登录自己的github账号(其他平台类似),创建一个新的repository, 添加README、.gitignore和license,点击下方的绿色按钮创建远程仓库

创建一个开源的repository.png

如果要删除某个库,找到这个库的Settings,删除库的入口在最底部。

2、提交项目代码并打好tag标签

远程库与本地项目关联有两种方法:
第一种,在本地新建文件夹TestKit,使用git clone命令把远程库clone到本地,在文件夹下创建或添加项目。

//终端切换到文件夹TestKit目录下
 cd /Users/userName/Desktop/TestKit 

//clone远程库
 git clone https://github.com/XXX/TestKit.git

//把项目文件放到新建的文件夹TestKit下
...

//提交当前文件夹下的所有文件到暂存区
git add .

//提交
git commit -m "提交说明"

//上传远程库,master是远程分支名称
git push origin master

第二种,在项目根目录下使用git remote add命令把远程库和本地项目关联起来。

//初始化git仓库
git init

//提交当前文件夹下的所有文件到暂存区
git add .

//提交
git commit -m "提交说明"

//关联远程库
git remote add origin https://github.com/XXX/TestKit.git

//指定origin为默认主机,如果加了这一步,上传远程库可以不带-u参数
git remote

//上传远程库,master是远程分支名称
//本地分支推送到origin主机,同时指定origin为默认主机,
//后面就可以不加任何参数使用git push,
//也可解决git建立远程关联时出现fatal ... upstram的问题
git push -u origin master

git仓库是隐藏文件,如果创建后项目根目录下看不到,使用快捷键shift+cmd+.可显示或隐藏文件,或使用命令

//显示
defaults write com.apple.finder AppleShowAllFiles -boolean true; killall Finder
//隐藏
defaults write com.apple.finder AppleShowAllFiles -boolean false; killall Finder

打tag标签,标签要与后面的podspec文件里的version参数一致

//打本地标签
git tag v1.0.0

//提交标签到远程
git push --tags
  • 附常用的git命令汇总:

//初始化git仓库
git init 

//添加当前文件夹下的所有文件到暂存区                           
git add .

//查看状态,红色字体表示本地改动没有提交,绿色字体表示已提交到了暂存区没有commit                                       
git status

//提交
git commit

//提交带提交说明,如果第一次使用,会提示输入github的账号密码                                
git commit -m ‘注释’   

//查看提交日志             
git log

//更新remote索引
git fetch

//推送
git push

//推送到远程master分支
git push origin master 

//本地分支推送到origin主机,同时指定origin为默认主机,
//后面就可以不加任何参数使用git push,
//也可解决git建立远程关联时出现fatal ... upstram的问题
git push -u origin master 

//按标签推送到远程
git push origin ‘标签,比如v1.0.0’ 

//关联远程仓库               
git remote add origin <URL>

//打标签
git tag '版本'

//打标签带描述
git tag -a '版本' -m '描述'

//标签提交到远程 
git push --tags

//删除本地标签
git tag -d v0.0.1

//远程删除标签
git push origin :v0.0.1

//查看当前所有分支
git branch        

//创建分支
git branch dev              

//检出分支
git checkout dev

//创建并检出分支
git checkout -b dev

//查看分支及hash值和提交信息
git branch -v

//把dev分支合并到当前分支
git merge dev

//删除分支dev
git branch -d dev

//强制删除分支dev,若没有其他分支合并就删除,-d会有提示 -D不会提示
git branch -D dev

//修改分支,分支dev改为kdev
git branch -m dev kdev

//强制修改分支,与其他分支有冲突也会创建
git branch -M dev kdev

3、创建并编辑.podspec索引文件

podspec官方语法说明 Podspec Syntax Reference

在项目根目录下创建podspec索引文件,文件名与项目名一致

//比如现有项目TestKit
pod spec create TestKit
或
pod spec create TestKit.podspec

然后编辑这个文件

Pod::Spec.new do |spec|

  # ―――  基本信息  ―――  #
  #spec文件名,也是使用pod搜索或安装时用的名字
  spec.name         = "TestKit"  
  # spec版本号
  spec.version      = "1.0.0"  
  # 简介
  spec.summary      = "常用组件"
  # 描述,description内容比summary要长一些,否则会有警告
  spec.description  = "常用组件和扩展"
  # 主页
  spec.homepage     = "https://github.com/huhansan/TestKit"   
  # spec.screenshots  = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"

  # ―――  开源协议  ―――#
  # spec.license      = "MIT"   
  spec.license      = { :type => "MIT", :file => "LICENSE" }

  # ―――  作者信息  ―――#
  spec.author       = { "huhansan" => "123456789@gmail.com" }   
  # Or just: spec.author    = "huhansan"
  # spec.authors            = { "huhansan" => "123456789@gmail.com" }
  # spec.social_media_url   = "http://twitter.com/huhansan"

  # ―――  平台信息  ―――#
  # spec.platform     = :ios
  # 平台及使用版本,ios平台,系统版本11.0及以上
  spec.platform     = :ios, "11.0"
  #  When using multiple platforms
  # spec.ios.deployment_target = "5.0"
  # spec.osx.deployment_target = "10.7"
  # spec.watchos.deployment_target = "2.0"
  # spec.tvos.deployment_target = "9.0"

  # ―――  git源信息  ―――#
  # 下面几种写法都可以,注意tag值,要保证与项目提交的tag一致:
  //指定tag值
  # spec.source = { :git => "https://github.com/huhansan/TestKit.git", :tag => 1.0.0 }
  //取spec.version
  # spec.source = { :git => "https://github.com/huhansan/TestKit.git", :tag => spec.version }    
  //tag带有前缀 "v" 
  spec.source = { :git => "https://github.com/huhansan/TestKit.git", :tag => "v#{spec.version}" } 
  //版本hash值
  # spec.source = { :git => "https://github.com/huhansan/TestKit.git", :commit => "c8706d6" }
  
  # ―――  资源管理  ―――#
  # 代码文件
  // “*” 表示匹配所有文件
  // “*.{h,m}” 表示匹配所有以.h和.m结尾的文件
  // “**” 表示匹配所有子目录
  spec.source_files  = "TestKit/Classes/**/*.{h,m,swift,xib,xcassets}"

  # ―――  资源信息  ―――# 
  # spec.resource  = "icon.png"
  # spec.resources = "Resources/*.png"
  # spec.preserve_paths = "FilesToSave", "MoreFilesToSave"

  # 使用resources方式引用资源文件
  spec.resources = ['Assets/Images/*.png', 'Assets/Resource/*']
  # 使用spec.resources方式是将资源文件copy到目标工程(Example工程)
  # 最后和目标工程的图片文件以及其他同样使用resources的Pod的图片文件,统一打包为一个Assets.car
  # 优点:可以使用 .xcassets 指定资源文件、不需要用硬编码方式获取图片
  # 缺点:可能会导致每个库和主工程之间的同名资源冲突
  # 硬编码方式:[NSBundle bundleForClass:[self class] compatibleWithTraitCollection:nil];


  # 资源文件打包成bundle,避免资源文件冲突
  spec.resource_bundles = {
      'TestKitBundle' => ['TestKit/Classes/**/*.storyboard'],
      'TestKitImgBundle' => ['Assets/Images/*.png']
  }
  # 使用spec.resource_bundles方式是会为指定的资源打一个.bundle,.bundle包含一个Assets.car,
  # 获取图片的时候要严格指定.bundle的位置,很好的隔离了各个库或者一个库下的资源包。避免资源同名冲突。
  # 优点:可以使用.xcassets指定资源文件、可以避免每个库和主工程之间的同名资源冲突
  # 缺点:获取图片时可能需要使用硬编码的形式来获取,比如想访问TestResourceBundle的资源:
  # [NSBundle bundleForClass:[self class].resourcePath stringByAppendingPathComponent:@"/TestResourceBundle.bundle"]


  # 不包含资源
  spec.exclude_files = "Classes/Exclude"
  # 对外开放的头文件地址,如果不指定会默认加载源代码所有头文件
  spec.public_header_files = "AFNetworking/*.h" #静态库时必须有
  
  # ―――  工程链接库  ―――# 
  # 引用系统公有framework,用“,”分割,去掉后缀 .framework
  spec.framework  = "UIKit"
  spec.frameworks = "UIKit", "AnotherFramework"

  # 引用系统静态库,去掉头尾的lib,用“,”分割
  spec.library   = "z"
  spec.libraries = "iconv", "xml2"
  
  # 引用自己生成的framework,用“,”分割 
  # 路径写从.podspec所在目录为根目录的相对路径,带后缀 .framework
  spec.vendored_frameworks = 'TestKit/Frameworks/*.framework'

  # 引用自己生成的.a静态库(必须以lib打头)
  spec.vendored_libraries = "TestKit/Libraries/libTestKit.a"

  # ――― 工程配置 ――― #
  # 是否是arc模式
  spec.requires_arc = true  

  # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
  
  # 依赖的第三方类库
  # spec.dependency "JSONKit", "~> 1.4"
  spec.dependency "RxSwift"
  spec.dependency "RxCocoa"
  ...

  # 配置xcode的other flag
  spec.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '$(inherited) -undefined dynamic_lookup' }
  # spec.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-lObjC' }

  # 指定SDK为静态库
  spec.static_framework  =  true

  # ――― 类库依赖 ――― #
  # 将单独的功能拆分为一个子模块,只想用子模块功能的时候只需在pod中引入子模块,不需要引入库的所有文件

  //子模块Reachability
  spec.subspec 'Reachability' do |ss|
    ss.source_files = 'TestKit/Classes/Reachability/**/*.{h,m,swift}'
    ss.dependency "AFNetworking/Reachability", '~> 3.0'
  end

  //子模块Downloader
  spec.subspec 'Downloader' do |down|
    down.source_files = 'TestKit/Classes/DownLoader/**/*'
    down.dependency "AFNetworking"
  end
  # Podfile中配置:
  # pod 'TestKit', '~> 1.0.0', :subspecs => ["Reachability", "Downloader"]
  # 或
  # pod 'TestKit/Reachability', '~> 1.0.0'
  # pod 'TestKit/Downloader', '~> 1.0.0'

end

提交前验证.podspec文件的合法性,也可以跳过验证环节直接提交,提交时会先验证本地.podspec文件的合法性再上传到trunk,最后会将上传的.podpec文件转换为需要的json文件。

# 无需联网
pod lib lint TestKit.podspec 
或
# 联网检查sepc repo并关联tag
pod spec lint TestKit.podspec 

--verbose:有些非语法错误是不会给出错误原因的,这个时候可以使用--verbose来查看详细的验证过程来帮助定位错误。
--use-libraries:表示使用静态库或者是framework,这里主要是解决当我们依赖一些framework库后校验提示找不到库的时候用到。
--allow-warnings:表示允许警告。
--sources=‘master,privateSpecs':指定源,比如你的私有pod同时依赖了公有库和私有库,你必须指定源才行,因为默认只会去公有源中查找对应的依赖

如果依赖了其他的第三方库

pod spec lint TestKit.podspec  --verbose --allow-warnings --sources="cocoapods库地址,私有库远程地址"

如果其他第三方私有库又依赖了其他的库,需增加--use-libraries

pod spec lint TestKit.podspec  --verbose --use-libraries --allow-warnings --sources="cocoapods库地址,私有库远程地址"

显示绿色的TestKit.podspec passed validation. 表示校验通过。

XXX.podspec应该在没有任何错误或警告的情况下通过验证。若验证过程中有错误,验证失败,修改后再次验证,直到通过验证。

  • 附.podspec验证时的参数:

Usage:

    $ pod lib lint [PODSPEC_PATHS ...]

      Validates the Pod using the files in the working directory.

Options:
 --quick                                  Lint skips checks that would require to
                                             download and build the spec
    --allow-warnings                         Lint validates even if warnings are
                                             present
    --subspec=NAME                           Lint validates only the given subspec
    --no-subspecs                            Lint skips validation of subspecs
    --no-clean                               Lint leaves the build directory intact
                                             for inspection
    --fail-fast                              Lint stops on the first failing platform
                                             or subspec
    --use-libraries                          Lint uses static libraries to install the
                                             spec
    --use-modular-headers                    Lint uses modular headers during
                                             installation
    --use-static-frameworks                  Lint uses static frameworks during
                                             installation
    --sources=https://cdn.cocoapods.org/     The sources from which to pull dependent
                                             pods (defaults to
                                             https://cdn.cocoapods.org/). Multiple
                                             sources must be comma-delimited
    --platforms=ios,macos                    Lint against specific platforms (defaults
                                             to all platforms supported by the
                                             podspec). Multiple platforms must be
                                             comma-delimited
    --private                                Lint skips checks that apply only to
                                             public specs
    --swift-version=VERSION                  The `SWIFT_VERSION` that should be used
                                             to lint the spec. This takes precedence
                                             over the Swift versions specified by the
                                             spec or a `.swift-version` file
    --include-podspecs=**/*.podspec          Additional ancillary podspecs which are
                                             used for linting via :path
    --external-podspecs=**/*.podspec         Additional ancillary podspecs which are
                                             used for linting via :podspec. If there
                                             are --include-podspecs, then these are
                                             removed from them
    --skip-import-validation                 Lint skips validating that the pod can be
                                             imported
    --skip-tests                             Lint skips building and running tests
                                             during validation
    --test-specs=test-spec1,test-spec2,etc   List of test specs to run
    --analyze                                Validate with the Xcode Static Analysis
                                             tool
    --configuration=CONFIGURATION            Build using the given configuration
                                             (defaults to Release)
    --allow-root                             Allows CocoaPods to run as root
    --silent                                 Show nothing
    --verbose                                Show more debugging information
    --no-ansi                                Show output without ANSI codes
    --help                                   Show help banner of specified command

4、把.podspec提交到Cocoapods trunk

注册CocoaPods trunk账户,需要一个真实可用的邮箱用于邮件验证

pod trunk register 123456789@gmail.com 'huhansan'

也可在用户名后面跟描述信息

pod trunk register 123456789@gmail.com 'huhansan' --description='huhansan的trunk' --verbose

注册命令执行后会在对应邮箱收到验证邮件,点击验证链接完成验证,提交.podspec文件到trunk

pod trunk push TestKit.podspec

使用--allow-warnings忽略警告

pod trunk push TestKit.podspec --allow-warnings

如果使用了静态库或私有库中有.a文件,必须加上--use-libraries

pod trunk push TestKit.podspec --use-libraries --allow-warnings

提交成功后更新下本地cocoapods再使用pod search命令搜索

pod setup
...
pod search TestKit

如果搜索不到就清理下cocoapods的搜索索引文件search_index.json的本地缓存,然后再搜索

rm ~/Library/Caches/CocoaPods/search_index.json 
...
pod search TestKit
  • 附pod trunk命令汇总:

# 注册trunk  -  pod trunk register [EMAIL] [USERNAME]
$pod trunk register 123456789@gmail.com 'huhansan'

# 查看已注册信息  -  pod trunk me
# 包含账号的Name、Email、Since、Pods、Sessions,其中Pods为该账号向CocoaPods提交的所有的库
$pod trunk me

- Name:     huhansan
- Email:    123456789@gmail.com
- Since:    February 8th, 02:15
- Pods:
  - HHSKit
  - HHSUIKit
  - HHSComKit
  - HHSActionSheet
  - HHSProgressHUD
  - HHSDownloadManager
  - HHSNavigationController
  - HHSTabBarController
- Sessions:
  - April 1st, 05:09 -  August 7th, xx:22. IP: xxx.xxx.xx.xxx
  - April 4th, 20:44 - August 10th, xx:58. IP: xxx.xxx.xx.xxx
  - April 4th, 21:37 - August 12th, xx:33. IP: xxx.xxx.xx.xxx
  Description: huhansan的trunk

# 查看账号下某个库的信息  -  pod trunk info [POD REP NAME]
$pod trunk info HHSUIKit

HHSUIKit
 - Versions:
 - 1.0.1 (2015-11-09 05:43:23 UTC)
 - 1.0.2 (2016-03-12 12:08:47 UTC)
 - 1.0.5 (2017-10-18 08:14:53 UTC)
 - 1.0.6 (2018-11-25 16:28:27 UTC)
 - 1.1.0 (2019-12-07 04:49:24 UTC)
 - 1.1.1 (2020-12-09 11:12:05 UTC)
 - 1.1.3 (2021-12-16 10:18:15 UTC)
 - 1.1.5 (2022-02-17 10:59:12 UTC)
 - Owners:
 - huhansan 

# 不管添加还是删除某个库的拥有者,必须`pod trunk register`登录过并且操作的是登录账号所拥有的库
// 添加某个库的拥有者  -  pod trunk add-owner [POD REP NAME] [OWNER-EMAIL]
$pod trunk add-owner HHSUIKit 123456789@gmail.com

// 删除某个库的拥有者  -  pod trunk remove-owner [POD REP NAME] [OWNER-EMAIL]
$pod trunk remove-owner HHSUIKit 123456789@gmail.com

# 让某个库过期 -  pod trunk deprecate [POD REP NAME]
$pod trunk deprecate HHSUIKit

# 删除某个库的某个版本,该命令无法撤回  -  pod trunk delete [POD REP NAME] [VERSION]
$pod trunk delete HHSUIKit 1.0.1

# 发布库,path是PodRepName.podspec的路径,若处于同一级目录也可不加path  -  pod trunk push [PATH]
$pod trunk push HHSUIKit.podspec
...
done

5、可能会遇到的问题

1.关联远程库git remote add报错

如果报错:fatal: not a git repository (or any of the parent directories): >.git
原因是git没有初始化,先调用命令git init初始化

2.推送远程git push报错

如果报错:
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to >'https://github.com/XXX/TestKit.git'
或者
error: src refspec master does not match any.
error: failed to push some refs to >'https://github.com/XXX/TestKit.git'
主要原因都是远程库与本地库不同步,可以通过git pull命令进行代码合并
git pull origin master

拉取后如果还是会报一些警告⚠️⚠️⚠️

hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint: 
hint:   git config pull.rebase false  # merge
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint: 
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.

这是因为拉取后合并时不知道以谁为基准注:pull = fetch + merge,拉取时加上rebase参数
git pull --rebase origin master

还有种简单粗暴的方式:
git push -f origin master
表示强制提交到远程,会覆盖掉远程库,如果远程库是空的这种方式也不是不可以。

3.校验pod spec lint报错

如果报错:
Cloning into '/var/folders/6p/dkd3r6595633j5fms40_d04h0000gn/T/d20240201-3829-4qf1cn'...
warning: Could not find remote branch 0.2.0 to clone.
fatal: Remote branch 0.2.0 not found in upstream origin
这是因为组件库忘记打tag了,spec里的版本号对应的tag找不到,打好tag后重新校验即可

6、组件库与私有化

6.1.本地组件库的创建与使用

运行pod lib create AppCom命令创建一个名称为AppCom的组件库,需要关注以下几个问题

#平台
What platform do you want to use?? [ iOS / macOS ]
 > 
ios
#语言
What language do you want to use?? [ Swift / ObjC ]
 > 
swift
#是否创建demo工程
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

至此,系统会创建一个包含本地私有库的项目


创建的组件库目录

新版本的cocoapod会自动执行 pod install ,模板库加载完成后,会通过命令行打开刚创建的工程


示例工程

进入到刚创建的项目,可以看到 AppCom 文件夹,这个文件就是用来存储私有库需要的代码文件和资源文件(图片、xib,以及其他资源文件)

代码文件放到Classes目录,资源文件放到Assets目录

替换Classes目录里的文件


替换掉了原来的文件

回到示例工程pod installpod update --no-repo-update一下,文件才会被真正加载到工程里

工程目录

至此,我们得到了一个本地组件库,在需要使用这个组件库的BTest工程目录下新建个文件夹LocalLib,把AppCom组件放到新建的目录下
多个本地组件放到一起方便管理

在BTest工程的pod里添加本地组件


指定本地组件加载路径

运行pod install把组件加载到工程里

AppCom已被加载到主工程

6.2.私有化组件库

私有化组件库需要把组件库与私有的Spec Repo关联起来
什么是 Spec Repo
它是所有的开源Pods的一个索引容器,实际上就是个remote端在GitHub上的Git仓库,在本地的 ~/.cocoapods/repos 目录下可以看到有一个master文件夹,这个就是clone到本地的官方Spec Repo
我们需要创建一个类似 master 的私有 Spec Repo,同理这个私有的Spec Repo也要有一个远程端,我们创建一个Git仓库用来存储.podspec 版本文件。

第一步,组件库上传到远端

在github或其它平台创建一个私有的远程库AppCom,把本地AppCom组件库代码上传上去并打好tag,上传过程不再赘述。

第二步,回到组件库工程里,配置AppCom.podspec文件
AppCom.podspec

删掉多余的注释后,需要关注以下的内容

Pod::Spec.new do |s|
  # 库名
  s.name             = 'AppCom'
  # 版本号
  s.version          = '0.1.0'
  # 概要
  s.summary          = '公共组件'
  # 描述
  s.description      = '公共类、扩展的公共组件'
  s.homepage         = 'https://www.chaoren.com'
  # 许可证
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  # 创建用户
  s.author           = { 'huhansan' => 'huhansan666@timeltd.cn' }
  # 远程库地址
  s.source           = { :git => 'https://github.com/huhansan/AppCom.git', :tag => s.version.to_s }
  # 最低的系统支持版本
  s.ios.deployment_target = '10.0'
  # 源文件路径
  s.source_files = 'AppCom/Classes/**/*'
  # 库资源文件路径,会打包成bundle
  s.resource_bundles = {
     'AppCom' => ['AppCom/Assets/*.png']
  }
  # 头文件路径
  s.public_header_files = 'Pod/Classes/**/*.h'
  # 需要用到的系统库
  s.frameworks = 'UIKit', 'MapKit'
  # 依赖的第三方库
  s.dependency 'AFNetworking', '~> 2.3'
  
end

!!!需要特别注意的是AppCom.podspec文件里的版本号要与第一步里打的tag一致!!!

第三步,关联私有Spec Repo

在github或其它平台创建一个私有的远程库AppSpecs,创建好后需要把AppCom.podspec与AppSpecs做关联,在终端中执行命令:

pod repo add AppSpecs https://github.com/huhansan/AppSpecs.git

关联成功进入到~/.cocoapods/repos 目录,可以看到除了master还多了一个AppSpecs文件夹,里面存储的就是私有库的索引。
注意两点
第一点,私有库AppCom如果是给其他人使用,就需要给这个人AppCom仓库权限
第二点,他人使用这个私有库AppSpecs索引也需要有AppSpecs仓库的权限,并在本地执行关联命令

第四步,AppCom.podspec推送到远程AppSpecs

与发布库到官方cocoapods类似,需要把索引push到私有的索引库,也是先校验,没问题了再push,运行命令

pod spec lint  AppCom.podspec 

如果依赖了其他的第三方库

pod spec lint AppCom.podspec  --verbose --allow-warnings --sources="cocoapods库地址,私有库远程地址"

如果其他第三方私有库又依赖了其他的库,需增加--use-libraries

pod spec lint AppCom.podspec  --verbose --use-libraries --allow-warnings --sources="cocoapods库地址,私有库远程地址"

显示绿色的AppCom.podspec passed validation. 表示校验通过,校验通过后执行命令

pod repo push AppSpecs AppCom.podspec --allow-warnings

...

#当显示如下内容就代表push成功了
Updating the `AppSpecs' repo


Adding the spec to the `AppSpecs' repo

 - [Update] AppCom(0.1.0)

Pushing the `AppSpecs' repo

至此,组件库的私有化就制作完成了。
在其他项目里就可以像其他库一样引用

pod 'AppCom'

需要注意的一点,因为是私有库,在Podfile里除了官方的索引源,还需要加上私有库的索引源

source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/huhansan/AppSpecs.git'
6.3.组件库间通讯

市面上已经有很多种中间件、路由等方案
CTMediator
HHRouter
MGJRouter
JLRoutes

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