以前写过一篇 iOS 组件化实现的一些思路总结 ,这篇做为续集,聊一聊使用 Cocoapods
在iOS平台组件化的实现和集成。html
本文中的两个例子能够在 YTThirdPlatformManager 项目中找到。ios
Cocoapods
是iOS/osx平台的开发库管理工具,简单的配置而后执行安装命令 Cocoapods
会自动去下载第三方库而且作好相应的配置,简化了引入第三方库的流程,让开发更简单高效,是iOS开发的必备工具,使用 Cocoapods
做为组件化的工具是一个不错的选择。c++
安装和设计能够参考这篇文章: Cocopods安装和升级备忘录git
以一个测试模块解耦的场景实现简单项目的组件化,主要包含如下内容github
使用 pod lib create
建立项目,会遇到几个须要输入的地方,具体的解释看代码段中的注释sql
➜ DevPods pod lib create PTTestKit
Cloning `https://github.com/CocoaPods/pod-template.git` into `PTTestKit`.
Configuring PTTestKit template.
------------------------------
To get you started we need to ask a few questions, this should only take a minute.
If this is your first time we recommend running through with the guide:
- http://guides.cocoapods.org/making/using-pod-lib-create.html
( hold cmd and double click links to open in a browser. )
# 使用的语言
What language do you want to use?? [ Swift / ObjC ]
> Objc
# 是否包好测试工程,指定YES用于模块化的解耦测试
Would you like to include a demo application with your library? [ Yes / No ]
>
yes
# 集成的测试模块,不须要指定None
Which testing frameworks will you use? [ Specta / Kiwi / None ]
> None
# UI测试模块,不须要指定No
Would you like to do view based testing? [ Yes / No ]
> No
# 指定类前缀
What is your class prefix?
> PT
Running pod install on your new library.
复制代码
一个简单的 podspec 文件以下,具体字段的解释查看代码中的注释便可ruby
Pod::Spec.new do |s|
s.name = 'PTTestKit'
s.version = '0.1.0'
s.summary = 'Wow PTTestKit.'
# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!
# 长的描述信息
s.description = <<-DESC Wow this is a amazing kit, Enjoy yourself! DESC
# 提交到git服务区的项目主页,没提交能够指定任意值,但须要保留这一项,不然会报错
# attributes: Missing required attribute `homepage`.
s.homepage = 'https://github.com/flypigrmvb/PTTestKit'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
# 受权文件
s.license = { :type => 'MIT', :file => 'LICENSE' }
# 用户信息
s.author = { 'flypigrmvb' => '862709539@qq.com' }
# 提交到git上的源码路径,没提交能够指定任意值,但须要保留这一项,不然会报错
# attributes: Missing required attribute `source`.
s.source = { :git => 'https://github.com/flypigrmvb/PTTestKit.git', :tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
# 指定最低的ios版本
s.ios.deployment_target = '8.0'
# 源文件的路径
s.source_files = 'PTTestKit/Classes/**/*'
# 公共的头文件,按需设置
s.public_header_files = 'PTTestKit/Classes/Public/**/*.h'
# 私有的头文件,按需设置
s.private_header_files = 'PTTestKit/Classes/Private/**/*.h'
# 依赖的系统Framework,按需设置
# s.frameworks = 'UIKit', 'MapKit'
# 依赖其余的pod库,按需设置
# s.dependency 'AFNetworking', '~> 2.3'
end
复制代码
若是在建立Pod库项目的步骤集成了 Example 测试项目,在测试项目下的podfile默认包含了当前的Pod库项目bash
#use_frameworks!
target 'PTTestKit_Example' do
pod 'PTTestKit', :path => '../'
target 'PTTestKit_Tests' do
inherit! :search_paths
end
end
复制代码
切换到测试项目目录下,运行 pod install
命令,完了以后测试项目集成了Pod项目。下面是在测试项目中使用Pod库项目中一些功能的简单例z微信
#import "PTViewController.h"
#import <PTTestKit/PublicFile.h>
// !!private header 能够导入
#import <PTTestKit/PrivateFile.h>
// !!报错
//#import <PTTestKit/ProjectFile.h>
@interface PTViewController ()
@end
@implementation PTViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self addActionWithName:@"Test" callback:^{
NSLog(@"====");
}];
[self addActionWithName:@"PrivateFile" callback:^{
[PrivateFile test];
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[PrivateFile test];
}
@end
复制代码
以一个第三发组件集成的场景为例,实现分模块组件化,主要包含如下内容:app
pod库项目的建立流程和简单模块组件步骤一致,不在赘述
该文件建立了一个Core模块,用于存放抽象的接口、基类以及一些公用的工具类和头文件,以及几个子模块用于具体的第三方平台的实现。具体的内容能够查看如下代码中的注释内容
Pod::Spec.new do |s|
s.name = 'PTThirdPlatformKit'
s.version = '0.1.0'
s.summary = 'A short description of PTThirdPlatformKit.'
# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!
s.description = <<-DESC TODO: Add long description of the pod here. DESC
s.homepage = 'https://github.com/flypigrmvb/PTThirdPlatformKit'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'flypigrmvb' => '862709539@qq.com' }
s.source = { :git => 'https://github.com/flypigrmvb/PTThirdPlatformKit.git', :tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.ios.deployment_target = '8.0'
# 设置默认的模块,若是在pod文件中导入pod项目没有指定子模块,导入的是这里指定的模块
s.default_subspec = 'Core'
# 定义一个核心模块,用户存放抽象的接口、基类以及一些公用的工具类和头文件
s.subspec 'Core' do |subspec|
# 源代码
subspec.source_files = 'PTThirdPlatformKit/Classes/**/*'
# 配置系统Framework
subspec.frameworks = 'CoreMotion'
subspec.dependency 'SDWebImage'
# 添加依赖的系统静态库
subspec.libraries = 'xml2', 'z', 'c++', 'stdc++.6', 'sqlite3'
end
# 支付宝模块
s.subspec 'AlipayManager' do |subspec|
# 源代码
subspec.source_files = 'PTThirdPlatformKit/AlipayManager/**/*'
# 添加资源文件
subspec.resource = 'PTThirdPlatformKit/AlipayManager/**/*.bundle'
# 添加依赖第三方的framework
subspec.vendored_frameworks = 'PTThirdPlatformKit/AlipayManager/**/*.framework'
# 添加依赖系统的framework
subspec.frameworks = 'CoreTelephony', 'SystemConfiguration'
# 依赖的核心模块
subspec.dependency 'PTThirdPlatformKit/Core'
end
# QQ模块
s.subspec 'TencentManager' do |subspec|
# 源代码
subspec.source_files = 'PTThirdPlatformKit/TencentManager/**/*'
# 添加资源文件
subspec.resource = 'PTThirdPlatformKit/TencentManager/**/*.bundle'
# 添加依赖第三方的framework
subspec.vendored_frameworks = 'PTThirdPlatformKit/TencentManager/**/*.framework'
# 添加依赖系统的framework
subspec.frameworks = 'SystemConfiguration'
# 依赖的核心模块
subspec.dependency 'PTThirdPlatformKit/Core'
end
# 微博模块
s.subspec 'WeiboManager' do |subspec|
# 源代码
subspec.source_files = 'PTThirdPlatformKit/WeiboManager/**/*'
# 依赖的微博pod库
subspec.dependency 'WeiboSDK'
subspec.dependency 'PTThirdPlatformKit/Core'
end
# 微信模块
s.subspec 'WXManager' do |subspec|
# 源代码
subspec.source_files = 'PTThirdPlatformKit/WXManager/**/*'
# 依赖的微信pod库
subspec.dependency 'WechatOpenSDK'
subspec.dependency 'PTThirdPlatformKit/Core'
end
end
复制代码
podfile文件以下,能够导入主模块和任意的子模块的组合
#use_frameworks!
platform :ios, '8.0'
target 'PTThirdPlatformKit_Example' do
pod 'PTTestKit', :path => '../../PTTestKit'
# 主模块
pod 'PTThirdPlatformKit', :path => '../'
# 子模块快
pod 'PTThirdPlatformKit/AlipayManager', :path => '../'
pod 'PTThirdPlatformKit/TencentManager', :path => '../'
pod 'PTThirdPlatformKit/WeiboManager', :path => '../'
pod 'PTThirdPlatformKit/WXManager', :path => '../'
end
target 'PTThirdPlatformKit_Example_Developer' do
pod 'PTTestKit', :path => '../../PTTestKit'
pod 'PTThirdPlatformKit', :path => '../'
pod 'PTThirdPlatformKit/AlipayManager', :path => '../'
pod 'PTThirdPlatformKit/TencentManager', :path => '../'
pod 'PTThirdPlatformKit/WeiboManager', :path => '../'
pod 'PTThirdPlatformKit/WXManager', :path => '../'
end
复制代码
参考: guides.cocoapods.org/syntax/pods…
podspec文件添加添加
s.vendored_frameworks = 'PTDataModule/Frameworks/*.framework'
复制代码
须要用到podspec规则中的subspec和requires_arc
参考:
guides.cocoapods.org/syntax/pods…
guides.cocoapods.org/syntax/pods…
s.requires_arc = true
# no arc files rules
non_arc_files = 'PTDataModule/Classes/**/JSONKit.{h,m}'
s.exclude_files = non_arc_files
s.subspec 'no-arc' do |sna|
sna.requires_arc = false
sna.source_files = non_arc_files
end
复制代码
参考: guides.cocoapods.org/syntax/pods…
podspec指定 PTDataModule-prefixheader.pch 文件
s.prefix_header_file = 'PTDataModule/SupportFiles/PTDataModule-prefixheader.pch'
复制代码
PTDataModule-prefixheader.pch 文件内容
#import "UtilMacro.h"
#import "DebugConfig.h"
#import "TIMAdapter.h"
复制代码
有个坑,使用pod install 以后自定义的pch文件在项目中找不到了,可是内容会添加到PTDataModule-prefix.pch文件中
可使用这种方式,直接把须要导入的头文件使用参数的方式指定
参考:
guides.cocoapods.org/syntax/pods…
spec.prefix_header_contents = '#import <UIKit/UIKit.h>', '#import <Foundation/Foundation.h>'
复制代码
[!] The 'Pods-PTThirdPlatformKit_Example' target has transitive dependencies that include static binaries: (/Users/aron/PuTaoWorkSpace/Plush_devpods_developer/DevPods/PTThirdPlatformKit/Example/Pods/WechatOpenSDK/OpenSDK1.8.0/libWeChatSDK.a and /Users/aron/PuTaoWorkSpace/Plush_devpods_developer/DevPods/PTThirdPlatformKit/Example/Pods/WeiboSDK/libWeiboSDK/libWeiboSDK.a)
复制代码
解决办法:
#use_frameworks! (注释这个)
s.public_header_files = 'PTBehaviorStat/Classes/**/*.h', 'PTBehaviorStat/vendor/**/*.h'
s.vendored_library = 'PTBehaviorStat/**/*.a'
复制代码
--template 参数指定本地的 模板数据
参考:
stackoverflow.com/questions/1…
好比Pod开发库A依赖Pod开发库B,依赖的信息填写以下便可,不须要指定路径获取其余信息
s.dependency 'DevLibB'
复制代码
在测试工程或者客户端工程的的podfile文件中须要显示的导入DevLibB,这样便可
pod 'DevLibB', :path => '../../DevLibB'
复制代码
subspec.source_files = 'PTThirdPlatformKit/WeiboManager/**/*'
复制代码
若是配置(以下所示)是错误的路径,在客户端是找不到这个类的,须要检查源文件配置的是否正确
subspec.source_files = 'PTThirdPlatformKit/WeiboManager111/**/*'
复制代码
以上是我在使用cocoapods作组件化集成实践的一些总结和遇到的一些问题,但愿对有须要的朋友有帮助。