[CocoaPod]基于私有仓库的pod创建问题

问题列表

  1. pod spec lint命令,校验pod的代码和配置时是从git上拉取的代码进行编译;所以如果未创建git,会报以下错误:
    -> ServyouCocoaPodDynamicLayout (0.1.0)
    – ERROR | [iOS] unknown: Encountered an unknown error ([!] /Applications/Xcode.app/Contents/Developer/usr/bin/git clone http://192.168.110.114/jihq/ServyouCocoaPodDynamicLayout.git /var/folders/rg/f1ycrs553dq2z2dq7mt0mbh80000gn/T/d20160921-12602-1bx4f8v –template= –single-branch –depth 1 –branch 0.1.0

Cloning into ‘/var/folders/rg/f1ycrs553dq2z2dq7mt0mbh80000gn/T/d20160921-12602-1bx4f8v’…
remote: Not Found
fatal: repository ‘http://192.168.110.114/jihq/ServyouCocoaPodDynamicLayout.git/’ not found
) during validation.
如果未将代码上传到git上,会报以下错误:
-> ServyouCocoaPodDynamicLayout (0.1.0)
– ERROR | [iOS] unknown: Encountered an unknown error ([!] /Applications/Xcode.app/Contents/Developer/usr/bin/git clone http://192.168.110.114/jihq/servyoucocoapoddynamiclayout.git /var/folders/rg/f1ycrs553dq2z2dq7mt0mbh80000gn/T/d20160921-12686-1o6vj1q –template= –single-branch –depth 1 –branch 0.1.0

Cloning into ‘/var/folders/rg/f1ycrs553dq2z2dq7mt0mbh80000gn/T/d20160921-12686-1o6vj1q’…
fatal: Remote branch 0.1.0 not found in upstream origin
) during validation.
如果未在git上增加对应的tag值,报错与上面一样。
2. 文件目录
默认的头文件目录设置为:s.public_header_files = ‘Pod/Classes/**/*.h’;但是如果Classes目录中,你的代码文件夹层次结构超过两级,就会出现以下错误:
- ERROR | [iOS] file patterns: The public_header_files pattern did not match any file.
这是因为文件夹层次结构过浅,导致无法找到对应的文件;如果你的文件夹层次结构有三级,就应该修改成:s.public_header_files = ‘Pod/Classes/* * /* * /*.h’;
3. 修改代码文件后需要提交
问题1中有说,lint命令是从git上拉取文件,所以文件是以git为准。比如你在本地的Assets目录下新增了图片文件,但是没有push到git上,就会出现以下问题:
- ERROR | [iOS] file patterns: The resource_bundles pattern for ServyouCocoaPodDynamicLayout did not match any file.
明明podspec文件中的配置正确,本地的pod update —no-repo-update也是可以的,但lint就是不成功,这就是因为git上没有对应文件的原因;
4. 源文件配置
使用默认的源文件配置:s.source_files = ‘ServyouCocoaPodDynamicLayout/Classes/*/
可能会报以下错误:
- ERROR | [iOS] unknown: Encountered an unknown error (undefined method path' for nil:NilClass) during validation.
根据github的issue说明,这可能是cocoapod的bug,可以将配置改为:
s.source_files = 'ServyouCocoaPodDynamicLayout/Classes/**/**/*.{h,m}'
5. 如果当前pod基于其他私有pod,则每个需要其功能的单元都需要import其头文件;否则可能出现以下问题:
error: no known class method for selector 'xxx:'
6. 出现expected a type问题
出现如下问题:
- ERROR | [iOS] xcodebuild: ServyouCocoaPodDynamicLayout/ServyouCocoaPodDynamicLayout/Classes/DynamicLayout/DynamicLayoutModel/SVDynamicLayoutManager.h:37:57: error: expected a type
最开始看到该问题时,以为是Foundation框架没有引用进pod中,所以就在.m代码里import了头文件,然后s.framework里添加了Foundation,但都没有用;
然后在lint命令后加了 --verbose参数,看详细的出错日志,发现是在这里出现的错误:
/var/folders/rg/f1ycrs553dq2z2dq7mt0mbh80000gn/T/CocoaPods/Lint/Pods/ServyouCocoaPodDynamicLayout/ServyouCocoaPodDynamicLayout/Classes/DynamicLayout/DynamicLayoutModel/SVDynamicLayoutManager.h:99:39: error: expected a type
WithModel:(NSManagedObject *)modelDO;
错误的地方是NSManagedObject,然后我看了代码,发现该对象属于CoreData框架,但我的这部分功能依赖于基础的pod;所以按说不需要关心CoreData框架;可我看了之后才发现基础pod的podspec文件中并没有配置CoreData框架。。。。而且还竟然校验通过了。
我尝试着在自己的pod中引用CoreData的头文件,在s.framework中加入CoreData,但都没有效果。
没办法,我只能自己修改了基础的pod的配置。然后更新了私有仓库,可是问题依旧存在。
后来偶然运行了一下下面的命令:pod spec lint ServyouCocoaPodDynamicLayout.podspec --sources=ServyouCocoaPod_IOS,master --no-clean
然后看到了这样一句日志:
Pods workspace available at
/var/folders/rg/f1ycrs553dq2z2dq7mt0mbh80000gn/T/CocoaPods/Lint/App.xcworkspacefor inspection.
这个App.xcworkspace工作空间就是本地编译pod的工程,进入对应的目录,打开工程,编译,就可以看到日志中提示的错误。
我这时候才注意到,之前的错误日志中有一个地方被我忽视了:
- ERROR | [iOS] xcodebuild: ServyouCocoaPodDynamicLayout/ServyouCocoaPodDynamicLayout/Classes/DynamicLayout/DynamicLayoutModel/SVDynamicLayoutManager.h:37:57: error: expected a type
那就是错误的地方是.h文件。而我之前一直关注的.m文件。。在工程里面我很容易就发现出错的原因是因为缺少前向引用,只要用@class进行一些声明就可以解决上面的问题。
以前之所以没有这样的问题是因为在pch文件中统一引用了头文件,现在没有了pch文件,所以.h文件里便找不到对应类的声明,出现了expected a type的错误。
7. 解决了以上问题后就出现了下面两个问题:
/Users/jifeng/Library/Developer/Xcode/DerivedData/App-dpxkmrruvfndhjfuqdoultvoaiad/Build/Products/Release-iphonesimulator/ServyouCocoaPodDynamicLayout/ServyouCocoaPodDynamicLayout.framework/Headers/SVDynamicLayoutManager.h:9:9: error: include of non-modular header inside framework module 'ServyouCocoaPodDynamicLayout.SVDynamicLayoutManager' [-Werror,-Wnon-modular-include-in-framework-module]
\#import "SVObject.h"
^
1 error generated.
/var/folders/rg/f1ycrs553dq2z2dq7mt0mbh80000gn/T/CocoaPods/Lint/App/main.m:3:9: fatal error: could not build module 'ServyouCocoaPodDynamicLayout'
@import ServyouCocoaPodDynamicLayout;
~~~^~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.
遇到这个问题之后在网上搜索了下“include of non-modular header inside framework module”,网上大部分的解决方法是:将Build Settings中的Allow Non-modular Includes In Framework Modules设为YES,但一直没有讲出现问题的原因。
后来看到了一个简书的文章,简单说明了问题原因,并且提供了另一个解决办法:http://www.jianshu.com/p/a1d2d148fdd3
简单来说就是在podfile文件中写代码,动态地生成modulemap和umbrella文件。
最终感觉第二种解决方法有些取巧,怕以后出现问题,还是决定采用第一种方法。
首先通过lint命令的--no-clean参数查看编译工程,手动修改了第一个解决方法中提及的编译开关,改为YES后确实没有了问题。
但是创建一个pod显然不能手动的修改该设置,于是在官方的podspec语法介绍网页https://guides.cocoapods.org/syntax/podspec.html中查看,最终在build settings找到了三个可能相关的参数:compiler\_flags、pod\_target\_xcconfig、user\_target\_xcconfig。
首先尝试配置compiler\flags。因为看到官方的例子是spec.compiler_flags = '-DOS_OBJECT_USE_OBJC=0', '-Wno-format'
而我的错误信息中也有类似的-Wnon-modular-include-in-framework-module,所以我配置了spec.compiler_flags = '-Wnon-modular-include-in-framework-module',但是没有效果。
然后尝试配置pod\_target\_xcconfig。官方的例子是:spec.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-lObjC' }。这应该是对应的Build Settings里面的Other Link Flags设置。虽然明知道很可能是错误的,但我还是尝试设置成spec.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-Wnon-modular-include-in-framework-module' }。果然无效。配置中{}应该是字典类型的配置,=>之前的字符串是一个key值,现在需要先找到Allow Non-modular Includes In Framework Modules设置对应的key值。在Xcode的Quick Help中看到注释中Declaration CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES,尝试了一下spec.pod_target_xcconfig = { 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES' },发现没有效果。后来想到Xcode是可以通过命令行进行编译的,编译指令中可能会有对应的key值。然后虽然没有直接找到对应的key值,但是看到了xcodebuild有-showBuildSettings参数可以查看编译设置。所以就先手动将编译工程中的Allow Non-modular Includes In Framework Modules设成YES。然后通过xcodebuild -workspace App.workspace -scheme App -showBuildSettings查看了当前工程所有的设置,果然发现了这样一个常量CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES的值为YES。Quick Help中的声明是对的key值,但pod\_target\_xcconfig的配置不起作用。
最后尝试配置user\_target\_xcconfig,按照官方的例子,配置为:spec.user_target_xcconfig = { 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES' }。成功,lint命令只剩下warning。
不过看官方的解释,user\_target\_xcconfig和pod\_target\_xcconfig的区别在于user\_target\_xcconfig是对于编译工程中所有pod的设置,而pod\_target\_xcconfig只是针对当前pod的。所以如果多个pod的podspec中对user\_target\_xcconfig同一个值进行了设置,那么就可能存在冲突问题。但因为CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES在pod\_target\_xcconfig不起作用,只能按现在的配置来处理。
8. 将私有仓库拉到本地时可能会存在两个。
因为git存在两个地址,分别是git和http/https,所以有时候可能会在本地repos下出现两个基于同一个git的仓库,仓库名字不同。因为一开始Lint的时候是指定了仓库名的,所以能通过,但pod repo push的时候虽然指定了push的仓库名,但因为没有指定校验的仓库名,一旦你的pod依赖了私有仓库中的某个pod,校验时会出现类似[!] Found multiple specifications forSVLibrary (2.2.0)`:的错误。此时需要删除掉一个私有仓库,然后重新push才行。
9. podfile中使用私有仓库的pod
只是添加pod xxx,会提示找不到xxx。此时需要添加私有仓库和官方仓库的git。
source ‘[email protected]..:xxx/servyoucocoapod_ios.git’
source ‘https://github.com/CocoaPods/Specs.git’
10. CoreData的model文件需要配置在resouce中
s.resource_bundles = {
‘Images’ => [‘Pod/Assets/*.png’],
‘Models’ => [‘Pod/Classes///*.{xcdatamodeld,xcdatamodel}’]
}
如果不配置,应用的bundle中就找不到momd文件。
按上面的配置,你的model最终的目录是:
Frameworks/CocoaPodXXX.framework/Models.bundle/xxx.momd
在代码里获取文件路径的时候需要注意。

你可能感兴趣的:(iOS问题记录本,二十年目睹之怪BUG)