背景
公司准备对项目进行模块化, 要使用pod形式. 咱们做过
.framework
和.a
形式的sdk
. 这pod只是应用.制作还真不了解, 咱也不敢说,咱也不敢问. 没办法, 找资料呗. 度娘的强大实在让人头大. 千篇一律的复制. demo的需求可以满足.但开发中碰到的有太多太多情况了. 自己做的pod工程是私有的. 整理了一些自己遇到的问题. 希望能给其他朋友一些帮助.
正文
- 打开终端,
cd <文件目录地址>
(任意文件夹地址), 本人习惯Desktop位置
cd Desktop
- 开始创建pod工程
pod lib create Demo_podProject
- 紧接着会有一下信息
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 ]
//这里输入你是否需要生成一个 demo 应用
//这里最好 Yes 这样你可以查看你创建的库是否可以使用
> YES
Which testing frameworks will you use? [ Specta / Kiwi / None ]
// 这里输入你需要用到的测试框架,随意选
> None
Would you like to do view based testing? [ Yes / No ]
//是否做基于视图的测试 Yes/No 都可以
> No
What is your class prefix?
//输入前缀
> JR
回车后, demo会自动打开. 下面是我生成的项目结构
-
podspec
文件, 工程的配置信息文件, 非常重要
下面图片为demo初始样子
s.name = 'Demo_podProject'
# 工程的名字s.version = '0.1.0'
# 版本号s.summary = 'A short description of Demo_podProject.
#对你写的库进行简要的概述一下s.description = <<-DESC
TODO: Add long description of the pod here.
DESC
# 对写的库进行具体的使用方法说明及其他描述 (没觉得太多意义)s.homepage = 'https://github.com/eternal.glory91@gmail.com/Demo_podProject
#git库的地址首页,可以在开源中国创建你的库,不需要使用什么初始化方法,不要勾选 readmes.screenshots = 'www.example.com/screenshots_1
# 屏幕快照的地址,例如演示的 gif 文件 (一样觉得没有太多意义)s.license = { :type => 'MIT', :file => 'LICENSE' }
#许可证,type-类型
;file-文件
,这里不需要改变,使用默认,文件指向的文件名与工程中文件名要一致。s.author = { 'xxx' => 'xxxx@xx.com' }
# 作者信息:账户名
,账户邮箱地址
s.source = { :git => 'https://github.com/eternal.glory91@gmail.com/Demo_podProject.git', :tag => s.version.to_s }
# 输入邮箱如果你在开源中国申请的 git 账号,那么把你在开源中国创建的项目的 https 网址输入到这里,s.ios.deployment_target = '8.0'
#iOS 支持的最低级别,这里最低8.0s.source_files = 'Demo_podProject/Classes/**/*'
#你库文件存放的目录位置,这里通过文件 项目名.xcodeworkspace 打开 xcode,如今打了 pods -> Development Pods -> 工程名 -> 工程名 -> Classes 在 Classes 这个文件夹下我们存放我们创建的类文件(.h,.m文件)s.dependency 'AFNetworking', '~> 2.3'
# 如果你的公共库需要依赖其他库,那么打开这里的注释,例如AFNetworking,如果有多个,则依次往后排
重点
当我们使用到自己写的静态库
或bundle资源文件
时如何解决呢
framework
- 在工程目录结构中创建framework文件夹;路径结构
Desktop
->Demo_podProject
->Demo_podProject
->Framework
- 将自定义framework放入该文件夹下
-
podspec
文件中配置信息, 如下:
s.vendored_frameworks = 'xxxxx/Framework/*.framework'
#vendored_frameworks
是所依赖自定义库,Demo_podProject/Framework
查找的路径
Xcode12版本以上编译的framework需要注意
在
podspec
文件中需添加
s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
两句话
如果没有上述配置pod repo push
会报错
ld: building for iOS Simulator, but linking in dylib built for iOS, file ' XXX ' for architecture arm64
clang: error: linker command failed with exit code 1
bundle
- 在工程目录结构中创建resource文件夹;路径结构
Desktop
->Demo_podProject
->Demo_podProject
->resource
- 将bundle文件放入该文件夹下
-
podspec
文件中配置信息
s.resources = 'xxxxx/resource/*.bundle'
然后执行pod install
, 会发工程中创建Frameworks
与Resources
两个虚拟文件夹,并且库和资源文件包在各自文件下.
路径描述中的 * & ** 说明
*
匹配所有文件v*
匹配所有以v开头
的文件*.framework
匹配所有后缀为framework
文件 可以任意修改.看所需要后缀的文件**
递归匹配所有子文件夹
CocoaPods中bundle文件使用
正常工程中使用bundle文件使用方式,[[[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"name" ofType:@"bundle"]] resourcePath] stringByAppendingPathComponent:@"filename"]
;但在pod中使用样方式返回的是nil
.虽说都是用的bundleWithPath
.然而之前的是mainBundle
.指的是工程路径下的.CocoaPods路径不算.
解决方案
/**
获取文件所在name,默认情况下podName和bundlename相同,传一个即可
@param bundleName bundle名字,就是在resource_bundles里面的名字
@param podName pod的名字
@return bundle
*/
+ (NSBundle *)bundleWithBundleName:(NSString *)bundleName podName:(NSString *)podName {
if (bundleName == nil && podName == nil) {
@throw @"bundleName和podName不能同时为空";
} else if (bundleName == nil ) {
bundleName = podName;
} else if (podName == nil) {
podName = bundleName;
}
if ([bundleName containsString:@".bundle"]) {
bundleName = [bundleName componentsSeparatedByString:@".bundle"].firstObject;
}
//没使用framwork的情况下
NSURL *associateBundleURL = [[NSBundle mainBundle] URLForResource:bundleName withExtension:@"bundle"];
//使用framework形式
if (!associateBundleURL) {
associateBundleURL = [[NSBundle mainBundle] URLForResource:@"Frameworks" withExtension:nil];
associateBundleURL = [associateBundleURL URLByAppendingPathComponent:podName];
associateBundleURL = [associateBundleURL URLByAppendingPathExtension:@"framework"];
NSBundle *associateBunle = [NSBundle bundleWithURL:associateBundleURL];
associateBundleURL = [associateBunle URLForResource:bundleName withExtension:@"bundle"];
}
NSAssert(associateBundleURL, @"取不到关联bundle");
//生产环境直接返回空
return associateBundleURL?[NSBundle bundleWithURL:associateBundleURL]:nil;
}