Cocoapods私有库的创建和使用(2025)

一、Cocoapods的原理

1. 原理

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

我们从gem安装cocoapods成功之后,在本地的~/.cocoapods/repo目下的cocoapods文件夹下就存在了cocoapods远程仓库的所有索引,也就是specs文件。

通过一层层的查找可以找到与我们需要的第三方库名字一致的一个文件夹,但是文件夹里并没有我们所需的代码文件。

首先~/.cocoapods/repo/cocoapods/Specs/为什么这么分层呢?

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

如AFNetworking的32位MD5加密值为:a75d452377f3996bdc4b623a5df25820

那么存放的地址为 Specs/a/7/5/

为什么不是存代码

  1. 如果是存代码的话,那么~/.cocoapods/repo/cocoapods/Specs这个文件会存储成千上万的cocoapods第三库的代码,那么这个文件是会非常的庞大的,这是很不合理的。

  2. 所以cocoapods本身就不保存代码文件,它只保留一个库的描述,通过这个库的描述去git仓库去查找代码文件

2. tag和索引文件.podspec

使用git作为远程仓库push到cocoapods的情况下,git tag将作为这次push的版本号,这就是为什么repo/cocoapods下的第三方库文件夹中会有一些这样以版本号命名的文件夹。

每个版本对应的文件夹下有一个podspec文件,这个索引文件是库的描述(以SDWebImage为例):

{
  "name": "SDWebImage",
  "version": "5.21.1",
  "platforms": {
    "osx": "10.11",
    "ios": "9.0",
    "tvos": "9.0",
    "watchos": "2.0",
    "visionos": "1.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": "5.21.1"
  },
  "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,
  "frameworks": "ImageIO",
  "default_subspecs": "Core",
  "pod_target_xcconfig": {
    "SUPPORTS_MACCATALYST": "YES",
    "DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER": "NO"
  },
  "subspecs": [
    {
      "name": "Core",
      "source_files": [
        "SDWebImage/Core/*.{h,m}",
        "WebImage/SDWebImage.h",
        "SDWebImage/Private/*.{h,m}"
      ],
      "private_header_files": "SDWebImage/Private/*.h",
      "resource_bundles": {
        "SDWebImage": [
          "WebImage/PrivacyInfo.xcprivacy"
        ]
      }
    },
    {
      "name": "MapKit",
      "platforms": {
        "osx": "10.11",
        "ios": "9.0",
        "tvos": "9.0",
        "visionos": "1.0"
      },
      "source_files": "SDWebImageMapKit/MapKit/*.{h,m}",
      "frameworks": "MapKit",
      "dependencies": {
        "SDWebImage/Core": [

        ]
      }
    }
  ]
}

二、创建一个Cocoapods私有库

1. 在gitee创建一个存放podsepc的索引库

我们需要在自己的git服务器(github,gitee,gitlab)中创建一个保存podspec的仓库。最好保证仓库创建的时候是一个空仓库,不需要使用readme之类的文件去初始化它。否则会有git冲突的情况需要解决。

这里我们使用gitee去创建我们自己的索引库(LGHSpecs)

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

pod repo add [name] [url]

 

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

3. 创建存放源码的仓库

3.1 在git服务器(我这里使用gitee)上再创建一个仓库用于存放源代码。

 

3.2 在终端中执行pod lib create 名字创建一个cocoapods的demo文件。

执行如下的命令:

cd /Users/yol/Desktop            
pod lib create LHGKitModule
Cloning `https://github.com/CocoaPods/pod-template.git` into `LHGKitModule`.
Configuring LHGKitModule template.
Ignoring ffi-1.17.0 because its extensions are not built. Try: gem pristine ffi --version 1.17.0
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 double 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 ]
 > Yes

What is your class prefix?
 > LGH
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.

Running pod install on your new library.

Analyzing dependencies
Downloading dependencies
Installing FBSnapshotTestCase (2.1.4)
Installing LHGKitModule (0.1.0)
Generating Pods project
Integrating client project

[!] Please close any current Xcode sessions and use `LHGKitModule.xcworkspace` for this project from now on.
Pod installation complete! There are 2 dependencies from the Podfile and 2 total pods installed.

[!] Your project does not explicitly specify the CocoaPods master specs repo. Since CDN is now used as the default, you may safely remove it from your repos directory via `pod repo remove master`. To suppress this warning please add `warn_for_unused_master_specs_repo => false` to your Podfile.

 Ace! you're ready to go!
 We will start you off by opening your project in Xcode
  open 'LHGKitModule/Example/LHGKitModule.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`.

4. 开发组件

4.1 完成pod lib create之后会自动生成一个LHGKitModule的项目

4.2 在下图的路径(LGHKitModule/Classes)下删除replaceme.m添加文件并添加自己组件的文件和资源。

4.3 然后配置.podspec的内容:

可以借鉴ZLPhotoBrowser.podspec的写法或其他第三方库(AFNetworking)

Pod::Spec.new do |s|
  #组件名称
  s.name             = 'LGHKitModule'
  #组件版本
  s.version          = '1.0.0'
  #组件概述
  s.summary          = 'A short description of LHGKitModule.'
  #组件的描述
  s.description      = '自己开发中总结的一些有利于提高开发效率的工具组件'
  #组件的主页(最好是可以访问)
  s.homepage         = 'https://gitee.com/smoothV/LGHKitModule'
  #遵循的许可证
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  #作者
  s.author           = { '刘观华' => 'liuguanhua@yolanda.hk' }
  #从何处获取库的源代码或二进制文件。它定义了依赖库的物理来源路径,确保构建时能正确拉取代码。
  #组件源文件的路径
  s.source           = { :git => 'https://gitee.com/smoothV/LGHKitModule', :tag => s.version.to_s }
  #支持的ios开发最低版本
  s.ios.deployment_target = '10.0'
  #用于指定需要被包含到库(Pod)中的源代码文件路径。它决定了 CocoaPods 在集成该库时,会将哪些源文件(如 .h、.m、.swift 等)添加到用户的工程中
  s.source_files = 'LGHKitModule/Classes/**/*'
  #用于声明 Pod 库中需要公开暴露给外部使用者(即集成该 Pod 的主工程)的头文件(Header Files)。其核心目的是控制头文件的可见性
  s.public_header_files = 'LGHKitModule/Classes/**/{*}.h'
  # 资源文件
  s.resource_bundles = {
    'LGHKitModule' => ['LGHKitModule/Assets/*.png']
  }

end

关于s.source_files的写法:

//表示匹配WBAvoidCrash/Classes下所有文件(主目录和子目录,其中**相当于省略中间层级)
'LGHKitModule/Classes/**/*'
//表示匹配Classes所有以.h和.m结尾的文件
'LGHKitModule/Classes/*.{h,m}'
//表示匹配所有WBAvoidCrash目录下文件,不包含子目录
'LGHKitModule/*'
4.4 进入Example目录, 配置Podfile,将组件配置到Podfile中.

pod 'LGHKitModule', :path => '../'

4.5 之后执行pod install ,执行结束后
cd /Users/yol/Desktop/LHGKitModule/Example 
pod install

4.6 在LHGKitModule/Example下打开Xcode的项目,之后在PodsDevelopment Pods目录下就可以看到我们添加的文件了。

4.7 开发组件
4.7.1 要新增文件,我们直接在对应的文件夹下创建即可。
4.7.2 要更改文件内容,也是直接在文件里面修改即可。
4.8 组件的自测

我们可以在Example for LGHKitModule目录下,去添加我们的调试代码,来调试我们的组件

三、将索引库推送到远程索引仓库

此时我们已经开发好了我们的仓库

1. 首先将本地的LHGKitModule项目推送到远程的代码仓库LGHKitModule(https://gitee.com/smoothV/LGHKitModule.git)

1.1 现将本地的LHGKitModule项目里面的.git删除

1.2 将本地的LHGKitModule项目推送到远程仓库LGHKitModule(https://gitee.com/smoothV/LGHKitModule.git)
git init
git add .
git commit -m 'desc'
git remote add origin 'https://gitee.com/smoothV/LGHKitModule.git'
git push --set-upstream origin master

打上标签

#打标签
git tag -a 1.0.0 -m 'release version 1.0.0'
#推送标签到远程
git push origin 1.0.0

2. 索引库推送到远程索引仓库

2.1 使用命令将组件索引推送到远程索引仓库
2.1.1 先验证索引库

创建完成之后使用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

cd /Users/yol/Desktop/LGHKitModule pod lib lint LHGKitModule.podspec --allow-warnings --use-libraries --no-clean

2.1.2 将.podspec推送到远程索引仓库
cd /Users/yol/Desktop/LGHKitModule pod repo push LGHSpecs LHGKitModule.podspec --use-libraries --allow-warnings --skip-import-validation

完成以上内容就大功告成了。

关于pod lib lint 和pod repo push 中带有参数的解释:

2.1.2.1 报错一:

执行pod repo push LGHSpecs 报错: Your configuration specifies to merge with the ref 'refs/heads/master' from the remote, but no such ref was fetched.

解决问题:

远程仓库LGHSpecs(https://gitee.com/smoothV/LGHSpecs)当前是空的,随便创建文件(如:README.md)就可以了。

2.1.2.2 报错二:

执行QNDeviceSpecs.sh脚本如遇到报错: the repo 'QNSpecs' at '~/.cocospods/repos/QNSpecs' is not clean

执行脚本,报错:the repo 'QNSpecs' at '~/.cocospods/repos/QNSpecs' is not clean

解决方案:

/// 前往私有库目录文件下 
cd /Users/yol/.cocoapods/repos/QNSpecs 
/// 查看git文件状态 
git status /// clean git clean -f

2.2 使用脚本推送组件索引
2.2.1 在LGHKitModule/目录下新建LGHKitModule.sh脚本文件,并将脚本写入文件
# podspecs 上传

#当前需要更新的版本

version='1.0.0'

function update_podspecs() {
local podspecs
podspecs=$(echo "$@")
result=1
for podspec in ${podspecs[@]};do
echo ""
echo -e "\033[01;34m**正在上传 ${podspec}.podspec **\033[0m"
echo ""
pod repo push LGHSpecs ${podspec}.podspec --use-libraries --allow-warnings --skip-import-validation

if [ $? -ne 0 ]; then
echo ""
echo -e "\033[01;34m**${podspec}.podspec上传失败**\033[0m"
echo ""
result=0
break
else
echo -e "\033[01;34m**${podspec}.podspec上传成功**\033[0m"
fi
done
#判断是否都上传成功
if [ $result -ne 0 ]; then
echo ""
echo -e "\033[01;34m**SUCCESS**\033[0m"
echo ""
else
echo ""
echo -e "\033[01;34m**FAIL**\033[0m"
echo ""
fi
}

function update_tag() {
echo -e "\033[01;31m正在检查tag列表\033[0m"
git fetch
git tag --list | grep -e ${version}$
if [ $? -eq 0 ];then
echo ""
echo -e "\033[01;31m检测到当前tag已经标记,是否删除重新标记(y/n)\033[0m"
echo ""
#获取用户操作
read num
if [ ${num} == 'y' ];then
git tag --delete $version
git push origin :refs/tags/$version
echo "结果"
echo $?
git tag ${version}
echo "结果"
echo $?
else
echo ""
echo -e "\033[01;34m 终止上传 \033[0m"
echo ""
fi
else
git tag $version
fi
return $?
}

#开始
echo -e "\033[01;31m正在push...\033[0m"
git push
# 设置tag
update_tag
echo $?
#判断tag是否操作成功
if [ $? -nq 0 ]; then
echo ""
echo -e "\033[01;34m**tag标志失败 $version**\033[0m"
echo ""
echo -e "\033[01;34m 终止上传 \033[0m"
echo ""
exit 1
else
echo -e "\033[01;34m**tag标志成功 $version**\033[0m"
echo -e "\033[01;31m正在上传tags\033[0m"
git push --tags

# 这里替换成自己的脚本即可
update_podspecs LGHKitModule   
fi
2.2.2 执行脚本
cd /Users/yol/Desktop/LHGKitModule/ 
sh LGHKitModule.sh

3. pod search 查看私有库组件是否已经成功

执行pod search 'LGHKitModule' ,可以看到组件索引已经成功上传

四、在新项目中pod自己的私有库

1. 终端执行pod init 生成在Podfile文件,并在Podfile中添加pod 'LGHKitModule'

pod init

source 'https://gitee.com/smoothV/LGHSpecs.git' 
target 'ModuleDemo'
   do use_frameworks! 
   pod 'LGHKitModule' 

end

2. 终端执行pod install, 就可以将自己的私有库pod下来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值