Cocoapods 私有化踩坑

整理完记录下来。

各种文件路径错误

- ERROR | [iOS] file patterns: The `vendored_libraries` pattern did not match any file.

- ERROR | [iOS] file patterns: The `vendored_frameworks` pattern did not match any file.

- ERROR | [iOS] file patterns: The `resources` pattern did not match any file.

...

检查 podspec 内文件路径是否正确。

关于文件路径记住一个原则:

你的库路径(可能是线上 git 库也可能是本地 git 库) + 你的指定路径 = 要找的文件路径, 那么就一定没问题. 例如我的库路径是 ::git => '/Users/myUserName/Documents/XXXSDK' 而我指定的s.source_files = 'XXXSDK/Classes/**/*', 它们两个拼接, 正好是我各种源码文件的路径.

Source: The version should be included in the Git tag.

检查 s.version 是否与 s.source 对应的 tag 相同。

建议使用这种写法:

s.version   = "0.1.0"
s.source    = { :git => "http://gitlab...git", :tag => s.version.to_s }

二进制文件内 Warning 引起失败

- WARN  | source: Git SSH URLs will NOT work for people behind firewalls configured to only allow HTTP, therefore HTTPS is preferred.

添加 --allow-warnings 参数

有错误但是没有具体信息

- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.

有些非语法错误是不会给出错误原因的,这个时候可以添加 --verbose 参数查看错误详细信息。

静态依赖错误

- ERROR | [iOS] Encountered an unknown error (The 'Pods' target has transitive dependencies that include static binaries: (Path) during validation.

这个错误是因为依赖库 s.dependency 包含了 .a 静态库造成的。虽然这并不影响 Pod 的使用,但是验证是无法通过的。可以通过 --use-libraries 来让验证通过。

私有仓库找不到

[iOS] unknown: Encountered an unknown error (Unable to find a specification for `BBBPrivateSDK` depended upon by `AAAPrivateASDK`

podspec文件里指定了私有仓库依赖,如:

s.dependency 'BBBPrivateSDK'

pod lib lintpod repo push 均需要添加 --sources 参数。

如:

pod lib lint --sources=http://xxx/xxxPrivateSpecs.git, https://github.com/CocoaPods/Specs.git 

.a 文件名必须以lib开头

- ERROR | [iOS] file patterns: The `vendored_libraries` pattern did not match any file.

或者

library not found for XXX

这种情况大部分都是因为静态库的命名出现了问题。在加载静态库的时候,Xcode 会查找带有库名称和前缀 lib 的文件。例如,如果您的库名为 XXX.aXcode 将查找 libXXX.a,那么在加载库时就会失败。

Undefined symbols for architecture i386 / x86_64 ...

  • 缺少 系统框架 依赖

缺少 CoreTelephony 框架:

"_OBJC_CLASS_$_CTTelephonyNetworkInfo", referenced from:
    xxxx
  • 缺少 系统库 依赖

例如缺少 c++ 库:

"std::__1::__basic_string_common<true>::__throw_length_error() const", referenced from:
    xxxx
  • 缺少 三方库 / 私有库 依赖

例如缺少 AFNetworking :

"_OBJC_CLASS_$_AFHTTPResponseSerializer", referenced from:
    xxxx

具体缺了啥依赖可以查阅SDK开发文档,查看源码,或者根据错误信息去网上搜索。

  • 静态库没有编译该架构
Undefined symbols for architecture i386:
      "_varB", referenced from:
          +[AAAObject methodAAA:] in AAAPrivateASDK(AAAObject.o)
    ld: symbol(s) not found for architecture i386
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

应尽量让提供方补上!

折中方法可以添加 --skip-import-validation, 将跳过验证 pod 是否可以导入阶段。

pod lib lint 没问题, 项目内 pod install 之后编译报 Undefined symbols for architecture i386 / x86_64 ...

如果是 Objective-C 和 Swift 混编项目, Podfile 需要添加 use_framework! 关键字。这种情况下源代码和静态库混合在一起打包会出问题。(目前 cocoapods 1.6.1 版本)

动态库和静态库之间的依赖问题, 见:组件化-动态库实战

解决方法是 podspec 中添加:

s.static_framework = true #声明静态库
s.user_target_xcconfig = {'OTHER_LDFLAGS' => '-ObjC'} #声明加载源代码文件的 Objective-C 类

相关文档: static_framework

push 新版本 podspec 到 repo 之后发现二次修改

  1. commit 新的修改信息;
  2. tag -d 删除该版本对应的 tag;
  3. 重新添加 tag;
  4. 提交修改后的代码;
  5. git push --tags -f 提交修改后的 tag;

注意:GitLab 上已存在的 tag 不能通过 git push --tags -f 同步命令删除,得登陆网页端操作。

如果二次修改提交之前项目已经 pod install / update,则需要先清本地缓存之后再 pod install / update

清除本地 pod 缓存的步骤:

  1. 删除缓存目录 ~/Library/Caches/Cocoapods 里对应的源码;
    find ~/Library/Caches/Cocoapods -name "DemoSDK" | xargs -n1 -p rm -rf 输入 y/n 确认删除。
  2. 删除工程目录里的 Podfile.lock 文件;
  3. 删除工程 Pods 目录下对应的源码。

私有仓库创建好了,pod 引用之后文件层级关系丢失

  • 使用 header_mappings_dir 设置目录保留路径:
spec.header_mappings_dir = 'XXXSDK/Classes/**'

相关文档:header_mappings_dir

  • 使用 subspec 划分子仓库,参考 SDWebImagepodspec:

SDWebImage.podspec

相关文档:subspec

参考资料:

Cocoapods

动态库和静态库

标签:ios, framework, cocoapods, use_framework, swift