制作framework并发布Cocoapods私有库【Swift】

一、制作framework

1.创建APP工程,用来开发framework和测试

2.创建framework的Target,根据项目需要来命名,此处命名为TestSDK,创建步骤如下:



3.工程使用pod管理依赖三方库

使用终端cd到工程根目录,执行命令 pod init,打开生成的Podfile文件,添加framework所需的第三方库,如pod 'SnapKit',并执行pod install,然后打开TestDemo.xcworkspace文件

4.配置framework

设置支持版本


取消只编译当前架构

移除重复的架构
真机和模拟器编译后,framework中arm64架构重复,会导致合并失败,所以移除模拟器中的arm64架构

设置编译选项优化,给framework包瘦身

设置类型为静态库

Scheme切换到TestDemo,设置release

5.开发功能代码

如果让类和方法让外界可调用,需要用权限修饰,使用public,如果要提供OC调用,要使用@objc修饰
swift 不像OC可以暴露接口,在swift中 要想给别的工程调用接口,记得在类,方法或属性前加public。
swift权限控制符:
open 权限最大,可以被外界模块访问,继承重写
public 可以被外界工程访问
internal 默认文件创建时的权限,可以在本工程的访问
private 只可以在创建的文件内访问


5.1.framework中的资源文件的使用
1).图片资源

extension UIImage {
    class func ex_image(named name: String) -> UIImage {
        //图片放到 framework 的 bundle 中可使用
        let bundleName = "TestSDK.framework/ImageBundle.bundle/\(name)"
        if let image = UIImage(named: bundleName) {
            return image
        }
        return UIImage()
    }
}

2).文件资源

文件资源也可以放在bundle中,同样的调用方式

var filterData: [FilterModel] = load("filters.json") 
func load(_ fileName: String, as type: T.Type = T.self) -> T {
    let data: Data
    let mainBundle = Bundle.main.path(forResource: "TestSDK.framework/ImageBundle", ofType: "bundle")
    let fileBundle = Bundle.init(path: mainBundle ?? "")
    let path = fileBundle?.path(forResource: fileName, ofType: nil) ?? ""
    let file = URL(fileURLWithPath: path) 
    do {
        data = try Data(contentsOf: file)
    } catch {
        fatalError("无法初始化\(fileName)文件")
    } 
    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("无法解析\(fileName)文件")
    }
}

6.添加生成最终需要发布的framework的脚本
说明:关于framework编译和合并的脚本,我还是比较喜欢以下的方式,简单粗暴。
像新建一个shell脚本的target我也试过,framework中没有依赖三方还行,像我这种依赖三方库的,shell运行不通过,三方库会报错

# 真机和模拟器framework合并脚本
# 选中framework,分别在真机和模拟器编译成功即可
if [ "${ACTION}" = "build" ]
then
# 定义framework名称(替换为自己定义的名字即可)
SDK_NAME=TestSDK
# 输出路径
INSTALL_DIR=${SRCROOT}/Products/${SDK_NAME}.framework
# 真机路径
DEVICE_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphoneos/${SDK_NAME}.framework
# 模拟器路径
SIMULATOR_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphonesimulator/${SDK_NAME}.framework
# 如果输出路径已存在,则删除
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
# 创建输出路径
mkdir -p "${INSTALL_DIR}"
# 如果真机framework和模拟器framework都存在
if [ -d "${DEVICE_DIR}" ] && [ -d "${SIMULATOR_DIR}" ]
then
# 拷贝真机framework到输出路径
cp -r "${DEVICE_DIR}/" "${INSTALL_DIR}/"
# 拷贝模拟器framework中的modules到输出路径
cp -r "${SIMULATOR_DIR}/Modules/${SDK_NAME}.swiftmodule/" "${INSTALL_DIR}/Modules/${SDK_NAME}.swiftmodule"
# 合并真机framework和模拟器framework
lipo -create "${DEVICE_DIR}/${SDK_NAME}" "${SIMULATOR_DIR}/${SDK_NAME}" -output "${INSTALL_DIR}/${SDK_NAME}"
fi
fi

7.生成framework
选中TestSDK,分别在真机和模拟器编译一次即可,然后在项目的根目录中,Products文件夹里会有最终的framework


二、发布framework

cocoapods发布私有库的大致流程为:
1、GitHub上创建一个私有索引库,这个索引库存放的都是私有库的路径
2、GitHub、码云或者Coding等上创建一个私有库,存放的是整个私有库的所有源码
3、把私有库的.podspec文件push到私有索引库中
4、把私有索引库更新到本地repo中

1.创建私有索引库,并添加到本地repo中


终端执行pod repo add TestSpec https://github.com/rayraychow/TestSpec.git
然后执行pod repo即可查看有没有添加成功,有TestSpec即是成功

2.创建framework库


3.本地framework源码根目录下,创建.podspec文件
终端执行pod spec create TestSDK
生成文件后拖入Xcode工程中,取消copy勾选
podspec文件修改完后,把本地私有库代码和远端私有库关联,并把代码都push上去
1).git add .
如果报错fatal: not a git repository (or any of the parent directories): .git,使用git init创建git目录
2).git commit -m '修改的内容'
3).git push
4).git tag '0.0.1'
5).git push --tags
注意:每次push后都需要打tag,且tag和.podspec文件中的版本号要一致
如果报错Ld .../Build/Intermediates.noindex/App.build/Release-iphonesimulator/App.build/Objects-normal/arm64/Binary/App normal arm64
在podspec文件中加入:spec.pod_target_xcconfig = { 'VALID_ARCHS' => 'x86_64 armv7 arm64' }

Pod::Spec.new do |spec|

  spec.name         = "TestSDK"
  spec.version      = "0.0.1"
  spec.summary      = "A short description of TestSDK."
 
  spec.description  = <<-DESC
    这是描述区,这里的文字一定要比 spec.summary 中的内容长,
  否则spec远端验证可能会不通过
                   DESC
  # 这里是主页地址,可以写github私有库的主页地址
  spec.homepage     = "https://github.com/rayraychow/TestSDK"

  spec.license      = "MIT"
 
  spec.author             = { "贝勒" => "[email protected]" }
  # 这是可以应用的平台及系统限制
  spec.platform     = :ios, "12.0"
  
  # 这是私有库的路径,填写私有库的git clone 的链接就行
  spec.source       = { :git => "https://github.com/rayraychow/TestSDK.git", :tag => "#{spec.version}" }
  
  # 如果是想暴露源码,打开这行
  # spec.source_files  = "Classes", "Classes/**/*.{h,m}"
  # spec.exclude_files = "Classes/Exclude"
  
  # 此处暴露的是framework
  spec.vendored_frameworks = "Products/TestSDK.framework"
  
  # 此处声明swift版本
  spec.swift_versions = "5.0"
  
  # 此处声明支持的类型
  spec.pod_target_xcconfig = { 'VALID_ARCHS' => 'x86_64 armv7 arm64' }
  
  # 这是声明framework依赖的三方库
  spec.dependency "SnapKit"

end

4.校验podspec文件
1).本地校验:pod lib lint
2).从本地和远程验证:pod spec lint
3).依赖库(spec.dependency)中 如果包含.a文件,验证的时候出现错误。加上这个来让验证通过:--use-libraries
4).有警告导致不通过验证时,加上这个忽略警告:--allow-warnings
5).有错误导致不通过验证时,加上这个查看具体错误:--verbose
校验文件可以直接执行pod spec lint --allow-warnings
注意:进行验证时如果报错warning: Could not find remote branch 0.1.0 to clone. fatal: Remote branch 0.1.0 not found in upstream origin
说明没有上传代码到仓库,先进行代码上传,执行 git add . git commit git push ,然后 git tag等流程的上传。

5.把.podspec文件push到远程Spec私有索引库中
终端执行pod repo push TestSpec TestSDK.podspec --allow-warnings --skip-import-validation
如果出现
[!] Found multiple specifications for `SnapKit (0.17.0)`: -/Users/beile/.cocoapods/repos/master/Specs/1/f/6/SnapKit/0.17.0/SnapKit.podspec.json -/Users/beile/.cocoapods/repos/trunk/Specs/1/f/6/SnapKit/0.17.0/SnapKit.podspec.json时,加入命令--sources='https://github.com/CocoaPods/Specs.git'

6.发布podspec文件到公有库中
1).注册cocoaPods
终端执行pod trunk register 邮箱地址 '用户名' --verbose
这里我们一般使用github邮箱和用户名, 然后在你的邮箱中会收到确认邮件, 在浏览器中点击链接确认即注册成功。
2).验证cocoaPods
确保打开了邮件中的链接之后(正常加载出来就行),继续执行命令
pod trunk me
3).发布
pod trunk push TestSDK.podspec
该命令的执行过程:
a.更新本地 pods库 ~/.cocoaPods.repo/master
b.验证*.podspec格式是否正确
c.将 *.podspec 文件转成 JSON 格式
d.对 master 仓库进行合并、提交

7.使用(和正常的pod库使用方式一样)
唯一的区别是,因为是私有库,需要在podfile文件中额外添加源地址
一个是私有的索引库地址source 'https://github.com/rayraychow/TestSpec.git'
一个是cocoapods的cdn地址source 'https://cdn.cocoapods.org/'

你可能感兴趣的:(制作framework并发布Cocoapods私有库【Swift】)