cocoapods发布开源库记录

一.创建一个工程xxx

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

    WX20210903-143134.png

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

三. 安装CocoaPods

四.配置.podspec文件

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

    pod trunk me
    
  • 创建.podspec:

    pod spec create xxx //xxx为开源库的名称
    
  • 编辑.podspec: Cocoapods官方命令文档(可能需要翻墙)

    • 开源的一些编辑:
      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" => "00000@qq.com" }
      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的相关命令

十.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 <XXXKit/XXXKit-Swift.h>
         #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的办法)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容