CocoaPods实现管理库、发布库、组件化

CocoaPods管理第三方库

1、pod init自动生成Podfile
在这里插入图片描述

2、vim Podfile,取消platform的注释,注释use_frameworks!使用静态库,添加pod 'AFNetworking', '~> 3.2.1'
在这里插入图片描述

  • 2.1、不使用use_frameworks!则在Pods项目(前面为蓝色图标)的Products下生成.a文件;使用use_frameworks!则生成.framework文件。

3、执行pod install生成CBD.xcworkspace文件。

CocoaPods创建自己的库

创建复合项目和Framework

1、创建普通的项目:
在这里插入图片描述
2、点击TARGETS左下角的“+”号,添加一个Target,选择“iOS”->“Framework & Library”->“Framework”。
在这里插入图片描述
在这里插入图片描述
创建Framework之后,左侧导航面板会多一个“RCUtility”目录,中间面板TARGETS也会多一个“RCUtility”。
TARGETS选中RCUtility,Build Settings中Mach-O Type为“Dynamic Library”(这里选择动态库,并不影响其他项目比如CBD使用这个库时选择静态链接还是动态链接,这里的设置只影响本项目的编译设置)(Framework是一种打包方式,包含.a二进制文件+bundle资源文件+.h头文件,不一定是动态链接库,也可以使用静态链接的方式。)。
在这里插入图片描述
3、Framework的设置:

  • 设置前缀:选中左侧“Project Navigator”面板中的“RCUtilityDemo”项目(左侧图标是蓝色而不是黄色),在打开的右侧“File Inspector”面板下的“Project Document”->“Class Prefix”填入前缀如RC,这样新建的class都自动以RC开头命名。
  • 设置scheme:Stop按钮右侧(左侧是Build and then Run按钮)选中“RCUtility”(不是RCUtilityDemo),再次点击选择“Edit Scheme…”,在弹出的面板中选中"Run",在左侧“Info”->“Build Configuration”改为“Release”。
  • 设置Build Settings:TARGETS选中RCUtility,Build Settings下的“Build Active Architchture Only”->“Release”设置为NO(Debug可不修改)。

4、Framework中创建类主项目中使用Framework

  • 4.1、导航面板中选中“RCUtility”目录(注意不是RCUtilityDemo目录),新建一个类,将这个类.h文件加到“Build Phases”->“Headers”->“Public”(默认在Project中,右键该文件选择“Move to Public Group”)。

  • 4.2、主项目中使用Framework:

    • 4.2.1、TARGETS->“RCUtilityDemo”->“Link Binary With Libraries”加入RCUtility.framework(默认已经加入)。
      在这里插入图片描述
    • 4.2.2、在主项目的类.m文件中import自己创建的Framework的某个类的头文件.h,即可使用这个类的方法。

GitHub托管代码

1、本地仓库

  • 1.1、在终端cd到RCUtilityDemo目录(里面包含RCUtility、RCUtilityDemo和RCUtilityDemo.xcodeproj),执行git init
  • 1.2、创建.gitignore(在Sourcetree中添加本地仓库,可以看到哪些文件被修改,哪些文件应该加到.gitignore),然后commit全部文件。

2、远程仓库

  • 2.1、GitHub上新建仓库,名字填RCUtility,选择Public,不勾选README这些文件,创建一个空白仓库。
  • 2.2、关联远程仓库:git remote add origin https://github.com/rccrx/RCUtility.gitgit push -u origin master

发布到CocoaPods

1、cd到RCUtilityDemo目录,执行pod spec create RCUtility创建文件RCUtility.podspec(生成的文件的注释里面会有各个参数的说明,虽然最后需要删除这些注释)。
2、修改文件RCUtility.podspec如下:

Pod::Spec.new do |spec|

  spec.name         = "RCUtility"
  spec.version      = "0.0.1"
  spec.summary      = "A short description of RCUtility."
  spec.homepage     = "https://github.com/rccrx/RCUtility"
  spec.license      = "MIT"
  spec.author             = { "rccrx" => "rccrx@qq.com" }
  spec.platform     = :ios, "9.0"
  spec.source       = { :git => "https://github.com/rccrx/RCUtility.git", :tag => spec.version }
  spec.source_files  = "RCUtility"
  spec.requires_arc = true

end

3、添加LICENSE文件

  • 3.1、在GitHub上点击“Add file”->“Create new file”。
    在这里插入图片描述
  • 3.2、填入LICENSE,右边会出现“Choose a license template”按钮,点击跳转页面。
    在这里插入图片描述
  • 3.3、选择“MIT License”,点击“Review and submit”,
    在这里插入图片描述
  • 3.4、选择“Commit directly to the master branch”,点击“Commit new file”。
    在这里插入图片描述

4、拉取远程最新代码,包含LICENSE文件。
5、验证podspec文件,执行pod lib lint RCUtility.podspec --allow-warnings(如果是“pod spec lint RCUtility.podspec --allow-warnings”则会出现tag的ERROR),出现“RCUtility passed validation.”则验证通过,接下来要添加tag。
6、添加tag:执行git tag 0.0.1添加一个tag,(“git tag”可以显示本地所有tag,“git ls-remote --tags origin”可以显示远程所有tag),执行“git push --tags”推送tag到远程。
7、再次验证podspec文件,执行pod spec lint RCUtility.podspec --allow-warnings,出现“RCUtility.podspec passed validation.”则验证通过,不再出现tag错误。

8、发布到CocoaPods之前如果未注册CocoaPods,先注册

  • 8.1、先验证是否已经注册,执行pod trunk me,返回注册信息则已经注册;返回“[!] Authentication token is invalid or unverified. Either verify it with the email that was sent or register a new session.”则需要重新注册;返回“[!] There was an error fetching your info from trunk: execution expired”则已经成功注册,重试直到出现注册信息。
  • 8.2、注册CocoaPods执行pod trunk register xxx@qq.com "crx" --verbose,出现“[!] Please verify the session by clicking the link in the verification email that has been sent to xxx@qq.com”之后查看邮箱点击链接验证即可。

9、发布到CocoaPods

  • 9.1、执行pod trunk push RCUtility.podspec --allow-warnings,出现错误:
    在这里插入图片描述
    cocoapods版本为1.7.2,cocoapods-trunk版本为1.5.0,执行sudo gem uninstall cocoapods-trunk卸载cocoapods-trunk1.5.0版本,然后执行sudo gem install cocoapods-trunk -v 1.3.1安装cocoapods-trunk1.3.1版本(卸载时好像有提示cocoapods1.7.2需要cocoapods-trunk>=1.3.1,<2.0)(rubygems.org可以查看cocoapods-trunk有哪些版本,当前最新1.5.0,cocoapods最新1.10.1)。
  • 9.2、重新执行pod trunk push RCUtility.podspec --allow-warnings,出现“Updating spec repo ‘master’”要等1小时最后出现如下:
    在这里插入图片描述
  • 9.3、执行pod search RCUtility出现错误“[!] Unable to find a pod with name, author, summary, or description matching ‘RCUtility’”,先删除“~/Library/Caches/CocoaPods/”目录下的search_index.json文件,再重新执行search,会出现“Creating search index for spec repo ‘master’… ”,5min后出现搜索结果并且重新生成search_index.json。

10、将RCUtility.podspec文件commit到git仓库。

Framework添加单元测试

1、点击TARGETS左下角“+”,弹出窗口选择iOS->Test->Unit Testing Bundle,Product Name填“库名称+Tests”,Target to be Tested选择库RCUtility(不是RCUtilityDemo),添加之后,TARGETS会多一个RCUtilityTests,左侧导航窗口会多一个RCUtilityTests目录。
在这里插入图片描述
2、“#import “RCFirst.h””导入Framework中一个类,写一个以test开头的方法,方法里面写测试代码,点击test方法左边菱形执行测试用例,测试通过则菱形变成绿色。
2.1、“#import “RCFirst.h””出现警告“Missing submodule ‘RCUtility.RCFirst’”,则在RCUtility.h文件中加上“#import “RCFirst.h””即可消除警告(不加这句也不会影响其他项目通过cocoapods的方式使用这个库),加上之后又出现一个警告“Double-quoted include “RCFirst.h” in framework header, expected angle-bracketed instead”,通过设置TARGETS->“RCUtility”->“Build Settings”->“Quoted Include In Framework Header”为NO可以消除警告,或者改为“#import <RCUtility/RCFirst.h>”。

3、可以使用主项目测试Framework,也可以使用单元测试。

CocoaPods实现组件化

组件化的目的是为了不同产品共用相同模块,避免相同模块重复开发。

1、cd到任意目录如TempProjects下,执行pod lib create RCAudioEngine创建库,会在TempProjects目录下创建一个RCAudioEngine目录,里面包含Example目录(虽然设置了include a demo app为No但是还是创建了一个测试工程)、LICENSE、RCAudioEngine目录(里面包含这个库的类文件)、RCAudioEngine.podspec、README.md,并且已经初始化了git并且有提交。TempProjects->RCAudioEngine目录下的文件有些需要删除、有些需要保留、有些需要修改、有些位置需要移动,所以没有直接在CBD相关目录下执行pod lib create创建库。(生成的podspec等文件中用户名,与“git config --global user.name “abc””设置的用户名无关,与“pod trunk me”显示的用户名无关,可能与钥匙串中存储的“github.com的账户名称”或者“github.com Access Key for xxx的账户名称”有关,在钥匙串的所有项目中搜索github会显示相关项。)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2、在CBD目录下创建一个存放本地组件库的目录,命名为LocalPods。
3、在LocalPods目录下创建一个库目录RCAudioEngine,添加相关文件:
在这里插入图片描述

  • 3.1、将xx/TempProjects/RCAudioEngine目录下的LICENSE、READEME.md移动到这里(即xx/LocalPods/RCAudioEngine目录,之后的文件和创建目录都是放在这个目录下)。
  • 3.2、创建一个Classes目录,将任意文件如一对.h、.m放到这个目录下(这些文件之后可以删除)。
  • 3.3、将xx/TempProjects/RCAudioEngine目录下的RCAudioEngine.podspec移动到这里,修改如下:
    主要是修改s.source_files为库文件所在目录,其他保持默认,删除注释。
Pod::Spec.new do |s|
  s.name             = 'RCAudioEngine'
  s.version          = '0.1.0'
  s.summary          = 'A short description of RCAudioEngine.'
  s.homepage         = 'https://github.com/rccrx/RCAudioEngine'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { 'rccrx' => 'rccrx@qq.com' }
  s.source           = { :git => 'https://github.com/rccrx/RCAudioEngine.git', :tag => s.version.to_s }
  s.ios.deployment_target = '9.0'
  s.source_files = 'Classes/**/*'
end
  • 3.4、修改CBD的Podfile,添加pod 'RCAudioEngine', :path => './LocalPods/RCAudioEngine'(path是本地组件库RCAudioEngine的目录相对CBD的Podfile的位置),cd的CBD目录执行pod install,就会在左侧导航面板Pods工程下出现一个Development Pods目录,里面有本地组件库。
    在这里插入图片描述
    在这里插入图片描述

  • 3.5、如果需要资源目录(不需要不用创建),则:
    【如果使用静态库(即CBD的Podfile没有use_frameworks!),推荐使用“s.resource_bundles=xx”而不是“s.resources=xx”,因为resources中的图片会与主工程中的图片有重名风险。】

    • 3.5.1、使用resource_bundles

      • 3.5.1.1、在LocalPods/RCAudioEngine目录下创建一个目录Assets,里面放入任意一个文件比如d3.png。

      • 3.5.1.2、修改RCAudioEngine.podspec添加s.resource_bundles = { 'RCAudioEngine' => ['Assets/**/*'] },执行pod install,在Development Pods->RCAudioEngine下自动生成Resources目录,目录下有资源文件。

      • 3.5.1.3、不使用“use_frameworks!”,编译之后的CBD->Products下的CBD.app里面会包含RCAudioEngine.bundle文件(Assets.car中只包含添加到主工程CBD->CBD->Assets.xcassets中的图片)(并且工程Pods->Products下也生成RCAudioEngine.bundle文件),因此RCAudioEngine.bundle里面的文件使用方式为:(如果使用“use_frameworks!”则RCAudioEngine.bundle在CBD.app->Frameworks->RCAudioEngine.framework)
        在这里插入图片描述

        NSBundle *aeBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"RCAudioEngine" ofType:@"bundle"]]; // 使用“use_frameworks!”时无法通过这个方法获取bundle,path改为“[[NSBundle mainBundle] pathForResource:@"Frameworks/RCAudioEngine.framework/RCAudioEngine" ofType:@"bundle"]”
        UIImage *image = [UIImage imageNamed:@"d3" inBundle:aeBundle compatibleWithTraitCollection:nil];
        // imageNamed有缓存而imageWithContentsOfFile没有,且RCAudioEngine.bundle/Assets.car中的图片也可以用这个方法获取(参看3.5.1.4)
        // UIImage *image = [UIImage imageWithContentsOfFile:[aeBundle pathForResource:@"d3.png" ofType:nil]];
        

        兼容Podfile使用和不使用”use_frameworks!“两种情况的获取图片方法:

        + (NSBundle *)getRCAudioEngineBundle {
         	// 注意:这个类名必须是本模块即RCAudioEngine中包含的类
        	NSBundle *bundle = [NSBundle bundleForClass:NSClassFromString(@"RCMainTabBarController")]; // 当这个类不在framework中时,返回”xx/CBD.app“;在framework中则返回”xx/CBD.app/Frameworks/RCAudioEngine.framework“,所以可以兼容Podfile使用和不使用”use_frameworks!“两种情况
        	NSString *path = [bundle pathForResource:@"RCAudioEngine" ofType:@"bundle"];
        	NSBundle *aeBundle = [NSBundle bundleWithPath:path];
        	return aeBundle;
        }
        
        + (UIImage *)imageNamedInAudioEngineBundle:(NSString *)name {
        	return [UIImage imageNamed:name inBundle:[self getRCAudioEngineBundle] compatibleWithTraitCollection:nil];
        }
        

        使用“[UIImage imageNamed:@“d3.png”]”是无法获取图片的,不管是在RCAudioEngine模块中还是主工程CBD中都无法显示。而且,RCAudioEngine.bundle中的图片应该只在RCAudioEngine模块中使用,不应该在主工程CBD中使用,因为每个模块有自己的资源,而主工程使用模块暴露的公共接口而不应该使用模块的图片。

      • 3.5.1.4、如果在RCAudioEngine/Assets下创建Asset Catalog文件:如果在Development Pods->RCAudioEngine->Resources下创建一个RCAudioEngineAssets.xcassets(文件存储路径为RCAudioEngine下的Assets,Targets勾选RCAudioEngine-RCAudioEngine,就算不勾选或者勾选其他也会在pod install之后Target Membership自动变成RCAudioEngine-RCAudioEngine),则会生成一个Assets.car在工程Pods->Products->RCAudioEngine.bundle中,也在主工程CBD->Products->CBD.app->RCAudioEngine.bundle中(因为CBD.app会包含程序运行所需的二进制文件和资源文件。记得一定要shift+command+K进行clean之后重新编译,否则可能在RCAudioEngine.bundle中找不到Assets.car,如果使用“use_frameworks!”则Assets.car会在CBD.app->Frameworks->RCAudioEngine.framework->RCAudioEngine.bundle中,接下来的3.5.2如果先在Assets目录下创建bundle文件然后使用“s.resource = ‘Assets/RCAudioEngine.bundle’”,则编译之后的bundle也是在这个位置,所以资源管理建议直接用resource_bundles而不是resource属性),且CBD->Products->CBD.app->Assets.car中没有包含RCAudioEngineAssets.xcassets中的图片(用AssetCatalogTinkerer打开)。

    • 3.5.2、使用resources

      • 3.5.2.1、右键Development Pods->RCAudioEngine,选择New Group创建Resources目录,这个目录和Classes目录同级,这个目录之后可以放xx.xcassets等资源文件,比如选中这个目录,按Command+N新建文件,在弹出的窗口中选择iOS->Resource->Asset Catalog,文件存储路径为RCAudioEngine下的Resources,Group为Resources,Targets不勾选,确定之后会在Resources目录下生成一个文件RCAudioEngine.xcassets。
        在这里插入图片描述
      • 3.5.2.2、修改RCAudioEngine.podspec添加s.resources = 'Resources/**/*',否则pod install之后这个目录就不显示在Development Pods->RCAudioEngine。(或者在Finder中创建一个Res目录放入一张图片,然后s.resources = ‘Res/**/*’,执行pod install会在Development Pods->RCAudioEngine下生成Resources目录,名称不是Res。)
      • 3.5.2.3、添加到Res目录中的图片,可以直接在CBD主工程、RCAudioEngine库中通过“[UIImage imageNamed:@“d3.png”]”使用,因为这个图片直接在CBD->Products下的CBD.app里面,没有RCAudioEngine.bundle。
      • 3.5.2.4、添加到RCAudioEngine.xcassets中的图片,在编译时出现错误“Mutiple commands produce ‘xx/CBD.app/Assets.car’”也许是指主工程CBD下Assets.xcassets和工程Pods->Development Pods->RCAudioEngine下的RCAudioEngine.xcassets都生成名字为Assets.car的文件,暂时不解决这个问题,使用resource_bundles。
        在这里插入图片描述
  • 3.6、在Finder中RCAudioEngine/Classes目录下创建两个目录Public、Model(因为右键New Group会在Classes同级目录下生成新目录,所以在Finder中手动创建Classes下的子目录),在这两个目录中放入任意文件再执行pod install,会在Development Pods->RCAudioEngine下出现这两个目录(如果目录中没有文件则不出现)。(如果是将原本在Classes的文件拖动到新目录如Public中则有可能不出现Public目录,之后就算在Public中放入新文件执行pod install也不会在Development Pods->RCAudioEngine下出现Public目录,新文件直接在RCAudioEngine目录下,所以Classes目录下新建目录时,最好放入新文件。Classes下最好至少两个目录,否则有可能Development Pods->RCAudioEngine下不出现这个唯一的目录。)
    在这里插入图片描述

    • 3.6.1、删掉ViewController.h、ViewController.m、T1.h、T2.h(选中右键->Delete->Move to Trash),在Model中创建RCFirstModel.h.m、Public创建RCFirstPublic.h.m,弹出窗口的Targets勾选RCAudioEngine。
    • 3.6.2、在CBD主工程中使用这个两个类“#import “RCFirstPublic.h” #import “RCFirstModel.h””,报错“‘RCFirstPublic.h’ file not found”,执行“pod install”之后就不再报错了(每次新增删除文件都要pod install)。
    • 3.6.3、如果只想暴露Public目录下的文件给主工程使用,则修改RCAudioEngine.podspec添加s.public_header_files = 'Classes/Public/**/*.h',这样主工程“#import “RCFirstPublic.h””不会报错,“#import “RCFirstModel.h””报错。
    • 3.6.4、给RCFirstPublic添加方法aString,编译通过,运行时出现错误“+[RCFirstPublic aString]: unrecognized selector sent to class 0x104e5e298”,Shift+Command+K进行clean,然后重新run。
    • 3.6.5、修改RCAudioEngine库中的文件如RCFirstPublic之后,要执行pod install,才会在主工程中使用时有补全提示。
  • 3.7、prefix_header_file

    • 3.7.1、默认在Development Pods->RCAudioEngine->Support Files下自动生成RCAudioEngine-prefix.pch文件,如果不想生成这个文件,则修改RCAudioEngine.podspec添加s.prefix_header_file = false
    • 3.7.2、添加pch文件步骤(但是不推荐使用,因为cocoapods.org中提示Pod不应该污染其他库或用户工程的prefix header):选中Development Pods->RCAudioEngine->Pod新建文件“iOS->Other->PCH File”,名称RCAudioEnginePrefix,存储位置选Classes,Group选Pod,Targets不勾选,修改RCAudioEngine.podspec为s.prefix_header_file = 'Classes/RCAudioEnginePrefix.pch',执行pod install之后,这个文件出现在Development Pods->RCAudioEngine而不是其下的Pod中(如果文件的存储位置是RCAudioEngine,和LICENSE同级,且“s.prefix_header_file = 'RCAudioEnginePrefix.pch”,则pod install之后这个pch文件会在Pod中),文件中的内容都自动拼接到原RCAudioEngine-prefix.pch文件结尾。
  • 3.8、将本地组件库RCAudioEngine的代码加到主工程CBD的git

    • 3.8.1、因为之前测试时添加了一些文件,又删除了,导致Sourcetree的CBD仓库也显示这些文件,执行“git status”发现这些文件在“Changes to be committed:”显示为new file,在“Changes not staged for commit:”显示为deleted,执行“git restore --staged 文件如LocalPods/RCAudioEngine/Resources/RCAudioEngine.xcassets”,这样Sourcetree就不显示这些文件了。
    • 3.8.2、Sourcetree的CBD仓库勾选全部文件(特别是LocalPods目录下全部文件),commit。
      在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值