制作cocoapods库

制作cocoapods库

记录一下制作cocoapods的方法和可能遇到的问题

制作方法

创建项目

方法一:

根据提示创建项目, 会包含一个Example 项目(该命令会自动创建.podspec 和示例项目)

1
pod lib create XXXFramework

方法二:

从现有项目制作cocoapods, 仅创建一个.podspec

1
pod spec create XXXFramework

修改podspec

根据需要填写,这里只是一个简单版的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Pod::Spec.new do |s|
s.name = "XXXFramework"
s.version = "1.0.0"
s.summary = "概要信息"
s.description = <<-DESC
这里是该pod的描述
DESC
s.homepage = "https://github.com/XXXXXX/XXXFramework"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "melody" => "xxxx@xx.com" }
s.platform = :ios, "7.0"
s.source = { :git => "https://github.com/XXXXXX/XXXFramework.git", :tag => s.version }
s.source_files = "Classes", "XXXFramework/Classes/*" # 根据实际填写
s.requires_arc = true
s.dependency 'Alamofire', '~> 4.7' #这里添加依赖的组件
end

提交和发布

先上传git并打上tag

1
2
3
4
git add -a && git commit -m "update version 1.0.0." 
git tag '1.0.0'
git push
git push --tags

验证podspec

1
pod spec lint --verbose --allow-warnings

这里可能出现很多问题,根据提示逐个解决

成功之后pod trunk创建账号

1
pod trunk register yourname@email.com "yourname"

发布pod

1
pod trunk push XXXFramework.podspec --allow-warnings

成功

1
2
3
4
5
6
7
8
--------------------------------------------------------------------------------
🎉 Congrats

🚀 XXXFramework (1.0.0) successfully published
📅 December 14th, 04:57
🌎 https://cocoapods.org/pods/XXXFramework
👍 Tell your friends!
--------------------------------------------------------------------------------

问题解决

Swift 项目中导入 CommonCrypto

CommonCrypto是一个系统C语言库,在OC项目中可以直接#import<CommonCrypto/CommonCrypto.h>

正常在Swift项目中也可以在桥接文件中引入。可是制作framework没有桥接文件。这就有些麻烦了。

最终解决方案如下:

方法一:

  1. 创建一个Framework 工程

  2. 在framework工程中添加一个新的target, 选择 Cross-platform - Aggregate, 命名为 CommonCryptoModuleMap

  3. CommonCryptoModuleMap 添加一个 Run Script

    1
    2
    3
    4
    5
    6
    7
    mkdir -p "${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap"
    cat <<EOF > "${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap/module.modulemap"
    module CommonCrypto [system] {
    header "${SDKROOT}/usr/include/CommonCrypto/CommonCrypto.h"
    export *
    }
    EOF
  4. 在MyFramework的 Build Phases - Target Dependencies 中添加CommonCryptoModuleMap 的依赖

  5. 最后在Build Settings -> SearchPaths -> Header Search Paths 中添加 ${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap$(inherited)

这样在framework中就可以import CommonCrypto

但是使用这个方法必须要将 三方库编译成.framework包才可以。为了方便在开发中可以reveal代码,我不打算把它打成.framework包,所以这个方法废弃

方法二:

在.podspec 中添加一个脚本。在编译前将CommonCrypto 的头文件写入modulemap,即可实现引入CommonCrypto 的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
s.script_phase = {
:name => 'CommonCrypto',
:script => 'COMMON_CRYPTO_DIR="${SDKROOT}/usr/include/CommonCrypto"
if [ -f "${COMMON_CRYPTO_DIR}/module.modulemap" ]
then
echo "CommonCrypto already exists, skipping"
else
# This if-statement means we will only run the main script if the
# CommonCrypto.framework directory doesn not exist because otherwise
# the rest of the script causes a full recompile for anything
# where CommonCrypto is a dependency
# Do a "Clean Build Folder" to remove this directory and trigger
# the rest of the script to run
FRAMEWORK_DIR="${BUILT_PRODUCTS_DIR}/CommonCrypto.framework"
if [ -d "${FRAMEWORK_DIR}" ]; then
echo "${FRAMEWORK_DIR} already exists, so skipping the rest of the script."
exit 0
fi
mkdir -p "${FRAMEWORK_DIR}/Modules"
echo "module CommonCrypto [system] {
header \"${SDKROOT}/usr/include/CommonCrypto/CommonCrypto.h\"
export *
}" >> "${FRAMEWORK_DIR}/Modules/module.modulemap"
ln -sf "${SDKROOT}/usr/include/CommonCrypto" "${FRAMEWORK_DIR}/Headers"
fi',
:execution_position => :before_compile
}