CocoaPods 建立私有仓库(ObjC)

Cocoapods的原理

pod repo

经过Podfile文件执行pod install或者pod update往iOS项目中导入第三方库,其实是找到podspec文件中描述的git仓库(svn), 而后从git仓库clone到本地的。html

咱们从gem安装cocoapods成功以后,在本地的~/.cocoapods/repo目下的master文件夹下就存在了cocoapods远程仓库的全部索引,也就是spec文件。ios

cocoapods repo

经过一层层的查找能够找到与咱们须要的第三方库名字一致的一个文件夹,可是文件夹里并无咱们所需的代码文件。git

首先repo/master为何这么分层呢?github

  • 这是由于为了合理的对cocoapods数以万计的三方库索引,因此将三方库的名字进行了md5加密而后取前三个字母做为这个第三方库的前三个索引,这样每一个目录下存放的库就不会太多,从而减小查找时间。

为何不是代码文件?web

  • 由于cocoapods自己就不保存代码文件,它只保留一个库的描述,经过这个库的描述去git仓库去查找代码文件。

pod repo中的文件夹

使用git做为远程仓库push到cocoapods的状况下,git tag将做为此次push的版本号,这就是为何repo/master下的第三方库文件夹中会有一些这样的文件夹。xcode

每一个版本对应的文件夹下有一个podspec文件,这个文件是库的描述:bash

SDWebImage(4.4.6)的podspec服务器

{
  "name": "SDWebImage", 名字
  "version": "4.4.6", 版本号
  "platforms": { 支持的平台
    "osx": "10.9",
    "ios": "7.0",
    "tvos": "9.0",
    "watchos": "2.0"
  },
  "license": "MIT", 开源协议
  "summary": "Asynchronous image downloader with cache support with an UIImageView category.", 简述
  "homepage": "https://github.com/SDWebImage/SDWebImage", 主页
  "authors": { 做者
    "Olivier Poitrey": "rs@dailymotion.com"
  },
  "source": { 源文件仓库
    "git": "https://github.com/SDWebImage/SDWebImage.git",
    "tag": "4.4.6"
  },
  "description": "This library provides a category for UIImageView with support for remote images coming from the web. It provides an UIImageView category adding web image and cache management to the Cocoa Touch framework, an asynchronous image downloader, an asynchronous memory + disk image caching with automatic cache expiration handling, a guarantee that the same URL won't be downloaded several times, a guarantee that bogus URLs won't be retried again and again, and performances!", 描述
  "requires_arc": true, 是不是在ARC下
  "frameworks": "ImageIO", 须要的framework
  "default_subspecs": "Core", 默认的子库 有多个子库的状况下
  "subspecs": [ 子库 每一个子库能够做为一个独立的库引入到项目中
    {
      "name": "Core", 名字
      "source_files": "SDWebImage/{NS,SD,UI}*.{h,m}", 文件路径 经过通配符查找
      "exclude_files": [ 不包含的文件
        "SDWebImage/UIImage+WebP.{h,m}",
        "SDWebImage/SDWebImageWebPCoder.{h,m}"
      ],
      "tvos": { tvos平台下的配置
        "exclude_files": "SDWebImage/MKAnnotationView+WebCache.*"
      }
    },
    {
      "name": "MapKit",
      "platforms": {
        "osx": "10.9",
        "ios": "7.0",
        "tvos": "9.0"
      },
      "source_files": "SDWebImage/MKAnnotationView+WebCache.*",
      "frameworks": "MapKit",
      "dependencies": { 依赖的库
        "SDWebImage/Core": [

        ]
      }
    },
    {
      "name": "GIF",
      "platforms": {
        "ios": "7.0"
      },
      "source_files": "SDWebImage/FLAnimatedImage/*.{h,m}",
      "dependencies": {
        "SDWebImage/Core": [

        ],
        "FLAnimatedImage": [
          "~> 1.0"
        ]
      }
    },
    {
      "name": "WebP",
      "source_files": [
        "SDWebImage/UIImage+WebP.{h,m}",
        "SDWebImage/SDWebImageWebPCoder.{h,m}"
      ],
      "xcconfig": { xcode的配置
        "GCC_PREPROCESSOR_DEFINITIONS": "$(inherited) SD_WEBP=1",
        "USER_HEADER_SEARCH_PATHS": "$(inherited) $(SRCROOT)/libwebp/src"
      },
      "watchos": {
        "xcconfig": {
          "GCC_PREPROCESSOR_DEFINITIONS": "$(inherited) SD_WEBP=1 WEBP_USE_INTRINSICS=1",
          "USER_HEADER_SEARCH_PATHS": "$(inherited) $(SRCROOT)/libwebp/src"
        }
      },
      "dependencies": {
        "SDWebImage/Core": [

        ],
        "libwebp": [
          ">= 0.5"
        ]
      }
    }
  ]
}
复制代码

建立一个私有cocoapods仓库

建立存放podsepc的仓库

经过上述原理,若是建立一个私有的cocoapods仓库就不能将仓库的podspec文件发布到cocoapods的repo中。app

因此咱们须要在本身的git服务器中建立一个保存podspec的仓库。最好保证仓库建立的时候是一个空仓库,不须要使用readme之类的文件去初始化它。不然会有git冲突的状况须要解决。async

建立完仓库以后获取仓库地址 在terminal中执行pod的指令将仓库添加到本地的pod repo中。

pod repo add [name] [url]

添加完成以后再~/.cocoapods/repo中就能够看到和master同级的一个目录,也就是存放库索引的地方。

添加podspec仓库

固然也能够使用pod repo remove [name]移除repo。

建立存放源码的仓库并推送到私有cocoapods

在git服务器上再建立一个仓库用于存放源代码。

在terminal中执行pod lib create 名字建立一个cocoapods的demo文件。

pod lib create test
Cloning `https://github.com/CocoaPods/pod-template.git` into `test`.
Configuring test 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?
 > soc

复制代码

执行以后会从git克隆一个模板,并会问几个问题,依次按照需求选择便可。完成以后会打开一个Xcode project。

在上图的路径(也就是replaceme.m存放的目录)下添加文件并删除replaceme.m

进入Example目录 配置Podfile,将项目名称.podspec配置到Podfile中,若是有依赖库,顺便添加。

platform :ios, '8.0'

target 'SoCNetWork_Example' do
  pod 'SoCNetWork', :path => '../SoCNetWork.podspec'
  pod 'AFNetworking' # 依赖AFNetworking
  pod 'YYCache' # 依赖YYCache
end
复制代码

保存以后执行 pod update (可选参数:--verbose 能够查看详细的过程 | --no-repo-update 不升级本地的repo会快一些)

执行结束以后在PodsDevelopment Pods目录下就能够看到咱们添加的文件了。

添加文件

另外依赖的AFNetworkingYYCache也添加到项目中了。

编译一下有错改之,无错进行下一步。

编辑podspec文件

Pod::Spec.new do |s|
  s.name             = '名字'
  s.version          = '版本号 须要和git tag保持一致'
  s.summary          = '简述'
  
  # This description is used to generate tags and improve search results.
  # * Think: What does it do? Why did you write it? What is the focus?
  # * Try to keep it short, snappy and to the point.
  # * Write the description between the DESC delimiters below.
  # * Finally, don't worry about the indent, CocoaPods strips it!
  
  s.description      = <<-DESC
  TODO: 描述
  DESC
  
  s.homepage         = '主页 最好保证能够访问'
  s.license          = { :type => 'MIT', :file => 'LICENSE' } #开源协议
  s.author           = { 'SoC' => 'joeqq1028@163.com' } #做者
  s.source           = { :git => 'git仓库地址', :tag => s.version.to_s }
 
  s.ios.deployment_target = '8.0' #最低支持的系统版本
  
  s.source_files = 'SoCNetWorkOAuth1.0/Classes/**/*' #文件路径
  s.dependency 'AFNetworking' #依赖的库
  s.dependency 'YYCache' #依赖的库
end
复制代码

关于source_files

这里若是添加的目录有嵌套能够使用subspec来实现。

例如:

嵌套

OAuth1.0下面有一个oauthcore文件夹。

podspecsource_file项的填写,再也不须要s.source_file能够使用以下示例填写:

s.subspec 'OAuth1.0' do |ss|
    ss.source_files = '项目名/Classes/OAuth1.0/*.{h,m}'
    ss.subspec 'oauthcore' do |sss|
      sss.source_files = '项目名/Classes/OAuth1.0/oauthcore/*.{h,m}'
    end
  end
复制代码

关于搜索文件的通配符在cocoapods官网中已经描述的很清楚了


建立完成以后使用pod lib lint来验证podspec填写的准确性。能够选择参数:

  • --verbose 查看整个过程
  • --allow-warnings 容许一些警告经过验证 `若是验证出错,而project build success 能够尝试添加这个参数
  • --source 若是依赖的库是一个私有仓库建立的库,能够使用这个参数指定私有仓库的podspec仓库,除此以外最好将cocoapods公有库的source也指定一下.好比(pod lib lint --sources='[私有podsepec仓库地址],https://github.com/CocoaPods/Specs' --verbose --allow-warnings --no-clean

验证经过以后 须要将文件push到git仓库中:

git init
git add .
git commit -am 'desc'
git remote add origin 'url'
git push origin master
git tag 'tag'
git push --tags
复制代码

添加完成以后将podsepc添加到私有repo中使用命令

pod repo push [repo name] [name.podspec] --verbose --allow-warnings

可选参数一样包括上述的--source=,跟上面描述的同样,再也不赘述。

这样建立私有库的工做就完成了。

使用私有cocoapods仓库

使用私有仓库的时候须要在Podfile中指定source。

source 'repo git url' # 私有仓库(存放podsepc文件的仓库)git地址
source 'https://github.com/CocoaPods/Specs.git' # cocoapods 公用仓库地址

platform :ios, '8.0'

target 'CTVITNetWork' do
  pod 'name'
end
复制代码

当遇到使用依赖库建立子类的时候会在 .h 文件中引入依赖库的头文件 而这样一般会在 执行 pod repo push 的时候发生错误。这个时候在 pod repo push 命令中添加 --use-libraries 参数可解决这个问题。而若是 .h 文件对依赖库中类的引用是非必须的, 也能够将 依赖库中类的声明放到 .m 中, 以解决这个错误。

END

相关文章
相关标签/搜索