cocoapods发布开源库记录

一.创建一个工程xxx

  • 把需要开源的文件放到这个工程对应文件夹里,保证运行成功。(文件夹也会显示到开源库的目录结构),比如Category文件夹,对应NSURLSession
    WX20210903-143040.png

    WX20210903-143134.png

二.github创建一个仓库,并把工程xxx与这个仓库绑定(github实在太慢,用coding创建仓库替代了)

  • 上传代码到仓库后,记得打tag:(cocoapods的版本记录就是这个tag)
    git tag 1.0.0
    git push --tags
    
  • 码云coding仓库的创建与本地工程绑定

三. 安装CocoaPods

  • 没有安装cocoapods,m1芯片安装cocoapods
  • 更新cocoapods版本:
    pod --version  //查看版本
    sudo gen install cocoapods
    pod setup //低于0.33,需要更新
    

四.配置.podspec文件

  • 注册:(已经注册的先忽略)

    pod trunk me
    
  • 创建.podspec:

    pod spec create xxx //xxx为开源库的名称
    
  • 编辑.podspec:

    • 开源的一些编辑:
      Pod::Spec.new do |spec|
      spec.name         = "xxx"  //开源库名
      spec.version      = "1.0.0"   //开源版本号,对应仓库的tag
      spec.summary      = "iOS开发组件化" // 简介
      spec.description  = <<-DESC    
                      一些开发组件化   //描述 (DESC不能删掉)
                  DESC    
      spec.homepage     = "https://e.coding.net/xxx.git"   //开源库的仓库地址 
      # spec.screenshots  = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
      
    • 开源协议的编辑:(coding码云没有license,可以到github下载一个放到仓库)
      spec.license      = { :type => "MIT", :file => "LICENSE" }
      
    • 作者信息的编辑:
      #spec.author  = { "tucici" => "[email protected]" }
      spec.author    = "tucici"    // 二选一
      
    • 开源库发布的平台的编辑:
      spec.platform    = :iOS  //这里设置只发布iOS平台
      # spec.platform     = :ios, "5.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"
      
    • 开源库的资源编辑:
      spec.source = { :git => "#{spec.homepage}", :tag => "#{spec.version}" }
      
      • 其他常见的写法:
        spec.source = { :git => "https://github.com/xxx/xxx.git", :commit => "98emfox" }
        spec.source = { :git => "https://github.com/xxx/xxx.git", :tag => 1.0.0 }
        spec.source = { :git => "hhttps://github.com/xxx/xxx.git", :tag => spec.version }
        
        • commit => "98emfox"表示pod版本与git仓库指定的commit= 98emfox绑定
        • tag => 1.0.0表示pod版本与git仓库指定的tag=1.0.0绑定
        • tag => spec.version表示pod版本与仓库的tag保持一致。spec.version就是.podspec最开始编辑参数spec.version = "1.0.0"
    • 开源库需要包含的源文件:
      spec.source_files  = "CCKit", "CCKit/Category/*.{h,m}" 
      spec.exclude_files = "Classes/Exclude"
      # spec.public_header_files = "Classes/**/*.h"   //需要包含的头文件
      

      CCKit文件夹是与.podspec同一级,上面配置的结果是,开源库会包含CCKit/Category/里面所有的.h.m文件

    • 开源库依赖静态库/动态库的编辑:
      spec.frameworks = "Foundation", "UIKit"  //这里就只依赖官方库
      
    • 依赖第三方开源库的编辑:
      spec.dependency "AFNetworking", "~> 1.0.0"
      
    • 大体上配置就这样,其实看.podspec的注释,可以大概明白每个配置是干嘛的

五.验证.podspec

pod spec lint xxx.podspec --verbose
  • 验证成功提示:
    xxx.podspec passed validation.
    

六.成功发布

  • 发布:
    pod trunk push xxx.podspec
    
  • 成功:
    Updating spec repo `trunk`
    
    -------------------------------------------------------------------- ------------
      Congrats
    
      xxx (1.0.0) successfully published
      September 3rd, 04:29
      https://cocoapods.org/pods/xxxx
      Tell your friends!
    
  • 搜索发布的开源库xxx:
    rm ~/Library/Caches/CocoaPods/search_index.json
    
    pod repo update
    

    过几分钟后,搜索,就能成功显示,有时候可能需要等更久:

    pod search XXX
    
  • 删除已发布的版本:
     pod trunk delete ZHPageView 1.0.0
    

七.错误及解决:

  • Specs satisfying the `xxxx (~> 1.0.0)` dependency were found, but they required a higher minimum deployment target.:
    解决: 三方依赖库xxxx设置里支持最低的ios版本,所以本开源库设置ios版本要高于xxxx支持的ios版本
  • Encountered an unknown error (/usr/bin/xcrun simctl list -j devices:
    解决: Xcode->Preferences->Locations->Command line tools,选择一个Xcode版本
  • [!] The spec did not pass validation, due to 3 warnings (but you can use `--allow-warnings` to ignore them).:
    解决:
    pod spec lint xxx.podspec --verbose --allow-warnings
    

八.注意:

  • 每次更新完库文件,同时也要更新远程仓库的tag,在验证pod spec lint xxx.podspec --verbose的时候,要先把本地tag删掉,否则会报错xxxx...HEAD...xxxx错误
  • cocoapods本地有对应缓存,有时候即使已经改的可以发布了,由于设置的版本spec.version = "1.0.0",在本地已经有缓存了,验证发布的时候还是会报错,需要清理下本地缓存:pod cache list,找到相应文件路径,清理。

九.tag相关命令行:

  • 查看本地tag:
    git tag 
    
  • 创建本地tag:
    git tag 1.0.0
    
  • 创建含附注tag:
    git tag -a 1.0.0 -m '附注信息'
    
  • 查看详情日志:
    git log
    
  • 对历史commit打tag:
    git tag v1.0.0 06c0b98//(历史commit日志)
    
  • 删除本地tag:
    git tag -d v1.0.0
    
  • 删除远程tag:
    git push origin --delete tag 1.0.0
    
  • 删除远程分支:
    git push origin --delete 远程分支名字
    
  • 推送指定tag到远程:
    git push origin 1.0.0
    

十.OC与Swift混编,有子文件夹的开源库

  • OC与Swift混编到pods开源库:
      1. 一个开源库里不仅有OC类,还有Swif类。
      1. 并且在这个开源库里, Swift与OC还会互相调用。
      1. 并且Swift和OC还混合存在于不同的文件夹。
      1. 并且要求发布的开源库在pods里不是一股脑在一个文件夹显示所有文件,而是跟在project中一样,也就是说,如图:


        112212121.png
  • 解决:
    • Swift调用OC好说,跟平常app开发一样,在桥接文件里导入OC的头文件
    • OC调用Swift
      • oc文件引用 :
         #if FMWK
         #import 
         #else
         #import "XXXKit_Swift.h"///这文件是复制XXXKit-Swift.h的内容
         #endif
      
      • swift 类文件:
      @objc public class NotifyTool:NSObject {
         @objc public class func add(_ observer:Any){}
      }
      
      • swift 扩展分类文件:
       @objc public extension NSString{
           func color(_ alpha : Float) -> UIColor{ return (self as String).color(alpha)}
           func color() -> UIColor{return (self as String).color()}
        }
      
  • 问题1: 会报某个文件夹的OC文件里找不到Swift方法的错误, 原因是找不到XXXKit-Swift.h里的对应的方法
    • XXXKit_Swift.h这个文件是XXXKit-Swift.h的拷贝。因为app开发用到XXXKit-Swift.h就可以了。但是开源库不同文件夹里的OC调用不同文件夹的Swift方法,相当于不同project的OC调用不同project的Swift方法。那么在开发开源库的project里生成的XXXKit-Swift.h,就包含了所有不同文件夹的Swift方法,我们所需要的就是新建一个.h文件,拷贝XXXKit-Swift.h的内容,哪个文件夹的OC需要调用Swift,就把这个.h保存一遍。在开发开源库的p roject的Run Script添加脚本如下:
generated_header_file=${DERIVED_SOURCES_DIR}/*-Swift.h
# include_dir=${BUILT_PRODUCTS_DIR}/include/${PRODUCT_MODULE_NAME}/
include_dir=${BUILT_PRODUCTS_DIR}/include/${PRODUCT_MODULE_NAME}/


# 将编译器生成的 xxx-Swift 头文件拷贝到 build 目录下的 include 目录中
#mkdir -p ${include_dir}
#cp ${generated_header_file} ${include_dir}

# 去掉 xxx-Swift.h 文件头部注释中的编译器的版本号
sed -i "" "s/^\/\/ Generated by Apple.*$/\/\/ Generated by Apple/g" ${generated_header_file}

# 拷贝 xxx-Swift.h 文件到工程源码目录 
header_file_in_proj=${SRCROOT}/${PROJECT}-Swift.h
needs_copy=true
if [ -f "$header_file_in_proj" ]; then
   echo "${header_file_in_proj} 已存在"
   
   new_content=$(cat ${generated_header_file})
   old_content=$(cat ${header_file_in_proj})
   if [ "$new_content" = "$old_content" ];then
       echo "文件内容一致,无需再Copy:"
       echo "${generated_header_file} "
       echo "${header_file_in_proj} "

       needs_copy=false
   fi
fi

if [ "$needs_copy" = true ] ; then
   
   echo "文件内容不一致,需要Copy:"
   echo "复制文件: "
   echo "${generated_header_file} "
   echo "${header_file_in_proj} "

   cp ${generated_header_file} ${header_file_in_proj}
fi


# 拷贝 xxx-Swift.h 文件到开源库根目录得 /Extension文件夹下
header_file_in_path=${SRCROOT}/${PROJECT_NAME}/${PROJECT_NAME}/Extension/${PROJECT}_Swift.h
needs_copy_path=true
if [ -f "$header_file_in_path" ]; then
   echo "${header_file_in_path} 已存在"
   
   new_content=$(cat ${generated_header_file})
   old_content=$(cat ${header_file_in_path})
   if [ "$new_content" = "$old_content" ];then
       echo "文件内容一致,无需再Copy:"
       echo "${generated_header_file} "
       echo "${header_file_in_path} "

       needs_copy_path=false
   fi
fi

if [ "$needs_copy_path" = true ] ; then
   
   echo "文件内容不一致,需要Copy:"
   echo "复制文件: "
   echo "${generated_header_file} "
   echo "${header_file_in_path} "

   cp ${generated_header_file} ${header_file_in_path}
fi
  • 问题2: 会报某个文件夹的Swift文件里找不到OC方法的错误, 原因是Swift文件夹里找不到桥接文件.h,如果可以,也把桥接文件一样拷贝到Swift存在的文件夹里。
  • 问题3: 生成带子文件夹的.podspec配置
    spec.source_files  = "XXX/header/*.{h,m,swift,strings}"///总的开源库,
   # spec.exclude_files = "Classes/Exclude"
   spec.public_header_files = "XXX/header/*.h"
  #spec.prefix_header_file = "XXX/header/PrefixHeader.pch"

 ///依赖的本地子开源库(project)的一个文件夹,这个库在开发project的文件夹名  = ```header ```
spec.subspec 'XXX' do |ss|
ss.source_files = 'XXX/header/**/*.{h,m,swift,strings}
end
///依赖的本地子开源库(project)的一个文件夹,这个库在开发project的文件夹名  = ```header ```
spec.subspec 'CCTool' do |ss|
ss.source_files = 'XXX/CCTool/*.{h,m,swift,strings}'
ss.dependency 'XXX/CCTool'DSSss.dependency 'TCCKit/公用组件'
ss.dependency 'TCCKit/Extension'
end
  • 一切正常的话,就会发布个XXX开源库,XXX下面有两个文件夹headeCCTool
  • 总结:所有找不到文件,都是某个地方没设置好。一个一个检查,总能解决问题。

      1. 一个开源库的总文件下的各个子文件夹,其实就相当于根文件夹下面依赖了不同的库,只不过这些库么有发布到cocoapods,是一起的,因此要设置好.podspec文件依赖关系(重复问题3的办法),要避免循环依赖。
    • 2.在验证库时候,可能会一直出现找不到响应的方法/类等错误,这个就是不同文件夹的OC/Swift互相调用的问题了,说白了,就是XXX-Swift.h桥接文件没引用好。在同一个工程,我们可以直接把XXX-Swift.h桥接文件,导入到PrefixHeader.pch,就可以了。(重复问题1/问题2的办法)

你可能感兴趣的:(cocoapods发布开源库记录)