1.CocoaPods简介
CocoaPods是专门为iOS工程提供第三方依赖库的管理工具,通过CocoaPods,我们可以更方便地管理每个第三方库的版本,而且不需要我们做太多的配置,就可以直观、集中和自动化地管理我们项目的第三方库。
CocoaPods将所有依赖的库都放在一个名为Pods的项目下,然后让主项目依赖Pods项目。然后,我们编码工作都从主项目转移到Pods项目。Pods项目最终会编译为一个libPod-项目名.a静态库,主项目依赖于这个静态库。
对于资源文件,CocoaPods 提供了一个名为 Pods-resources.sh 的 bash 脚本,该脚本在每次项目编译的时候都会执行,将第三方库的各种资源文件复制到目标目录中。
CocoaPods 通过一个名为 Pods.xcconfig 的文件来在编译时设置所有的依赖和参数。
CocoaPods是用 Ruby 写的,并由若干个 Ruby 包 (gems) 构成的。在解析整合过程中,最重要的几个 gems 分别是:CocoaPods/CocoaPods, CocoaPods/Core, 和 CocoaPods/Xcodeproj。
2.CocoaPod的核心组件
-
CocoaPods/CocoaPod
这是一个面向用户的组件,每当执行一个 pod 命令时,这个组件都将被激活。该组件包括了所有使用 CocoaPods 涉及到的功能,并且还能通过调用所有其它的 gems 来执行任务。 -
CocoaPods/Core
Core 组件提供支持与 CocoaPods 相关文件的处理,文件主要是 Podfile 和 podspecs。 -
Podfile
Podfile 是一个文件,用于定义项目所需要使用的第三方库。该文件支持高度定制,你可以根据个人喜好对其做出定制。更多相关信息,请查阅 Podfile 指南。 -
Podspec
.podspec 也是一个文件,该文件描述了一个库是怎样被添加到工程中的。它支持的功能有:列出源文件、framework、编译选项和某个库所需要的依赖等。 -
CocoaPods/Xcodeproj
这个 gem 组件负责所有工程文件的整合。它能够创建并修改 .xcodeproj 和 .xcworkspace 文件。它也可以作为单独的一个 gem 包使用。如果你想要写一个脚本来方便地修改工程文件,那么可以使用这个 gem。
cocoPods工作原理:
- cocoPods 首先根据Podfile 文件要使用的库查找找到本地spec版本号
- 并根据其中文件找到对应git地址
- 使用git地址spec对应版本git 代码
- 拉取git代码并进行解压缩
其中我们如果要查看本地的spec路径的话,可以使用命令:
pod repo list
终端进入根目录 open .cocoapods/repos . 即可打开本地spec目录,也可以直接进入Path所标注的目录;
根据目录,可以查询到AFNetworking 的本地spec目录;每个目录版本中都有一个AFNetworking.podspec.json 文件内容/Users/a1/.cocoapods/repos/master/Specs/A/7/5/AFNetworking/3.2.1
{
"name": "AFNetworking",
"version": "3.2.1",
"license": "MIT",
"summary": "A delightful iOS and OS X networking framework.",
"homepage": "https://github.com/AFNetworking/AFNetworking",
"social_media_url": "https://twitter.com/AFNetworking",
"authors": {
"Mattt Thompson": "m@mattt.me"
},
"source": {
"git": "https://github.com/AFNetworking/AFNetworking.git",
"tag": "3.2.1",
"submodules": true
},
"requires_arc": true,
"public_header_files": "AFNetworking/AFNetworking.h",
"source_files": "AFNetworking/AFNetworking.h",
"prefix_header_contents": "#ifndef TARGET_OS_IOS\n #define TARGET_OS_IOS TARGET_OS_IPHONE\n#endif\n\n#ifndef TARGET_OS_WATCH\n #define TARGET_OS_WATCH 0\n#endif\n\n#ifndef TARGET_OS_TV\n #define TARGET_OS_TV 0\n#endif",
"platforms": {
"ios": "7.0",
"osx": "10.9",
"watchos": "2.0",
"tvos": "9.0"
},
"subspecs": [
{
"name": "Serialization",
"source_files": "AFNetworking/AFURL{Request,Response}Serialization.{h,m}",
"public_header_files": "AFNetworking/AFURL{Request,Response}Serialization.h",
"watchos": {
"frameworks": [
"MobileCoreServices",
"CoreGraphics"
]
},
"ios": {
"frameworks": [
"MobileCoreServices",
"CoreGraphics"
]
},
"osx": {
"frameworks": "CoreServices"
}
},
{
"name": "Security",
"source_files": "AFNetworking/AFSecurityPolicy.{h,m}",
"public_header_files": "AFNetworking/AFSecurityPolicy.h",
"frameworks": "Security"
},
{
"name": "Reachability",
"platforms": {
"ios": "7.0",
"osx": "10.9",
"tvos": "9.0"
},
"source_files": "AFNetworking/AFNetworkReachabilityManager.{h,m}",
"public_header_files": "AFNetworking/AFNetworkReachabilityManager.h",
"frameworks": "SystemConfiguration"
},
{
"name": "NSURLSession",
"dependencies": {
"AFNetworking/Serialization": [
],
"AFNetworking/Security": [
]
},
"ios": {
"dependencies": {
"AFNetworking/Reachability": [
]
}
},
"osx": {
"dependencies": {
"AFNetworking/Reachability": [
]
}
},
"tvos": {
"dependencies": {
"AFNetworking/Reachability": [
]
}
},
"source_files": [
"AFNetworking/AF{URL,HTTP}SessionManager.{h,m}",
"AFNetworking/AFCompatibilityMacros.h"
],
"public_header_files": [
"AFNetworking/AF{URL,HTTP}SessionManager.h",
"AFNetworking/AFCompatibilityMacros.h"
]
},
{
"name": "UIKit",
"platforms": {
"ios": "7.0",
"tvos": "9.0"
},
"dependencies": {
"AFNetworking/NSURLSession": [
]
},
"public_header_files": "UIKit+AFNetworking/*.h",
"source_files": "UIKit+AFNetworking"
}
]
}
3.CocoaPod本地私有库创建
首先进入终端:
//创建pods文件夹
mkdir pods
//进入pods文件夹
cd pods
//根据模板创建XZUIModel库 远程模板路径 https://guides.cocoapods.org/making/using-pod-lib-create.html
pod lib create XZUIModul
//之后会弹出一些选择项目
What platform do you want to use?? [ iOS / macOS ] 您想使用什么平台?
iOS
What language do you want to use?? [ Swift / ObjC 你想用什么语言?]
objc
Would you like to include a demo application with your library? [ Yes / No ]您想在库中包含一个演示应用程序吗?
YES
Which testing frameworks will you use? [ Specta / Kiwi / None ] 您将使用哪些测试框架
none
Would you like to do view based testing? [ Yes / No ]
NO
What is your class prefix?你的类前缀是什么?
XZ
这个时候就会创建一个库:
上传代码
-
我们要添加的代码应该放在Classes 中 ,新建2个model 放入文件夹中,这一步操作相当于对本地库进行了代码上传
-
进入终端对应的XZUIModul中的Example目录使用pod install对新加入的Model 给代码中进行添加
-
查看工程中,已经添加完代码了
在工程中Development Pods/Pod/ 目录下有XZUIModul.podspec 文件
#
# Be sure to run `pod lib lint XZUIModul.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
#库名称
s.name = 'XZUIModul'
#库版本好
s.version = '0.1.0'
#库的简介
s.summary = 'A short description of XZUIModul.'
# 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/Alan/XZUIModul'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type => 'MIT', :file => 'LICENSE' }
# 作者
s.author = { 'Alan' => 'zhaialan@sina.com' }
# 源
s.source = { :git => 'https://github.com/Alan/XZUIModul.git', :tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
#依赖版本
s.ios.deployment_target = '8.0'
s.source_files = 'XZUIModul/Classes/**/*'
# s.resource_bundles = {
# 'XZUIModul' => ['XZUIModul/Assets/*']
# }
# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit'
# s.dependency 'AFNetworking', '~> 2.3'
end
这样我们就对一个本地pod私有库创建成功;
私有库的引用
- 下面我们再来创建一个私有库:
- 进入pods目录pod lib create XZCommonModul 在新建一个工具类;
- 新建一个XZPersonModel继承于XZUIModul库中的XZModel 放到工程中
这个时候进入Example 中直接使用pod install 编译完成后,就会报错:这里看到报错原因是因为没有引入XZModel 类,但是这个属于基础模块,不能放在工具类;
这个时候我们就需要在这个库中导入XZUIModul 库,需要建立依赖
首先进入XZCommonModul.podspec文件中,添加私有库依赖
//添加AF库和Masonry库
s.dependency 'AFNetworking', '~> 3.2'
s.dependency 'Masonry'
//添加私有库XZUIModul依赖
s.dependency 'XZUIModul'
//在库的pch文件中引入头文件
s.prefix_header_contents = '#import "Masonry.h"','#import "UIKit+AFNetworking.h"','#import "XZModle.h"'
导入私有库还需要Podfile 文件中进行修改
platform :ios, '8.0'
target 'XZCommonModul_Example' do
pod 'XZCommonModul', :path => '../'
#添加UIModule源这个源就是新添加的,因为这个目录和我的在同一目录新建的私有库,需要../../才能找到XZUIModul 库具体情况可根据自己情况进行查看
pod 'XZUIModul', :path => '../../XZUIModul'
target 'XZCommonModul_Tests' do
inherit! :search_paths
end
end
导入之后,就可以正常使用第三方库,以及自己的私有库文件;这里需要注意的是,如果添加第三方库可能会报错,这个可以查询本地的spec中有没有你需要添加的具体版本;
4.CocoaPod私有库坑点
如果需要在库中添加image或者json,html 等文件可以在Assets 目录中添加
添加完成后如果要在别的工程中使用的话需要用:还需要在工XZCommonModul.podspec 文件中修改这里需要注意的是原始工程是*.png 只添加png 文件,但是我的里面有添加json 所以去掉了.png ,添加所有文件
s.resource_bundles = {
'XZCommonModul' => ['XZCommonModul/Assets/*']
}
因为这种加载方式所以我们在使用图片的时候也不能直接使用:[UIImage imageNamed:@"share_wechat”],这种情况因为image不在本地macho文件的根目录,所以我们需要找到图片索引位置:
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
imageView.backgroundColor = [UIColor magentaColor];
NSString *bundlePath = [[NSBundle bundleForClass:[self class]].resourcePath stringByAppendingPathComponent:@"/Frameworks/XZCommonModul.framework/XZCommonModul.bundle"];
NSBundle *resoure_bundle = [NSBundle bundleWithPath:bundlePath];
imageView.image = [UIImage imageNamed:@"share_wechat" inBundle:resoure_bundle compatibleWithTraitCollection:nil];
[self.view addSubview:imageView];
/Frameworks/XZCommonModul.framework/XZCommonModul.bundle" 这个路径,
我们可以app的macho 中进行查找如下图:
查看到具体的bundle 路径,有的bundle 直接在根目录下,路径是有可能变化的(如果取其中的json 文件也是一样)
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(100, 220, 100, 50)];
label.backgroundColor = [UIColor magentaColor];
NSString *path = [resoure_bundle pathForResource:@"Contents" ofType:@"json"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSError* initError = nil;
id obj = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&initError];
label.text = obj[@"info"][@"author"];
[self.view addSubview:label];
这里其实还有个类似的问题,就是当我们将图片加入到工程的时候:
如果将share_weibo文件夹拖入到工程中:
这里的Create groups 和Create folder references的区别:这里对于工程中的实际区别就是对与安装的路径区别也就是说对于macho(也就是自己安装的ipa包)的区别,
这里我将share_qqZone文件夹使用Create folder references拖入工程将share_weibo文件夹使用Create groups拖入工程;
我们可以app的macho 中进行查找面查找XZCommonModul.bundle路径;
这里可以看出使用Create groups 方式,图片文件是在根目录:可以使用代码:
[UIImage imageNamed:@"share_weibo”]
但是使用Create folder references方式,图片访问就需要加上文件夹目录才可以访问:
[UIImage imageNamed:@"share_qqZone/share_qqZone"];
总结
本篇文章主要介绍了cocoapods私有库的本地创建,以及本地私有库引入另一个库和第三方库,同事描述了在使用私有库中的一些资源文件的坑点。Demo链接地址,其中有一部分注释在demo中有添加,欢迎大家前往git下载!
欢迎大家点赞,关注我的CSDN,我会定期做一些技术分享!未完待续。。