使用 cocoapods 的子规范构建 ios 框架的问题

Posted

技术标签:

【中文标题】使用 cocoapods 的子规范构建 ios 框架的问题【英文标题】:Problem building ios framework with subspec for cocoapods 【发布时间】:2019-01-17 17:55:56 【问题描述】:

这是我的 SDK 的 podspec:

#
#  Be sure to run `pod spec lint Core.podspec' to ensure this is a
#  valid spec and to remove all comments including this before submitting the spec.
#
#  To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
#  To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
#

Pod::Spec.new do |s|
  s.name             = "TiendeoCore"
  s.version          = "0.1.10"
  s.summary          = "Tiendeo Core"
  s.homepage         = "https://www.tiendeo.com"
  s.license          = 'Custom'
  s.author           =  "Tiendeo" => "info@tiendeo.com" 
  s.platform         = :ios, '10.0'

  #REMOTE 
s.source =  "http" => "https://tiendeo.jfrog.io/tiendeo/pods/TiendeoCore/TiendeoCore-0.1.10.zip" 

  #LOCAL#   s.source =  :git => "https://gitlab.tiendeo.com/ios/core-ios.git", :tag => s.version 
  s.dependency "Governor", "~> 0.2.5"
  s.dependency "AlamofireObjectMapper", "~> 5.2"
  s.dependency "Alamofire", "~> 4.8"
  s.dependency "RealmSwift", "~> 3.11.1"
  s.dependency "RxSwift", "~> 4.2.0"
  s.default_subspec = 'Lite'

  s.subspec 'Lite' do |lite|
    lite.name = "Lite"
    #REMOTE 
lite.framework = "TiendeoCore"
    #REMOTE 
lite.vendored_frameworks = 'TiendeoCore.framework'
     #LOCAL#     lite.source_files     = ["Source/**/*.swift", "Source/Core.h"]
     #LOCAL#     lite.public_header_files = ["Source/Core.h"]
     #LOCAL#     lite.resource_bundles = 
     #LOCAL#       'TiendeoCore' => ['Source/**/*.xib,png,jpg,json,xcdatamodeld,xcdatamodel,xcassets,ttf,lproj']
     #LOCAL#     
  end

  s.subspec 'Full' do |full|
    full.name = "Full"
    #REMOTE 
full.framework = "TiendeoCore"
    #REMOTE 
full.vendored_frameworks = 'TiendeoCore.framework'

    #LOCAL#     full.source_files     = ["Source/**/*.swift", "Source/Core.h"]
    #LOCAL#     full.public_header_files = ["Source/Core.h"]
    #LOCAL#     full.resource_bundles = 
    #LOCAL#       'TiendeoCore' => ['Source/**/*.xib,png,jpg,json,xcdatamodeld,xcdatamodel,xcassets,ttf,lproj']
    #LOCAL#     
    full.xcconfig = 
         'OTHER_SWIFT_FLAGS' => '$(inherited) -DFULLTIENDEOCORE'
    
    full.dependency "TiendeoAuth", "~> 0.0.6"
    full.dependency "FacebookCore", '~> 0.4.0'
  end


end

我正在构建一个 TiendeoCore.framework 以使用命令将其上传到 cocoapods(我有一个构建 .framework 并复制模拟器架构的脚本,我正在展示脚本):

xcodebuild -workspace "$WORKSPACE_PATH" -scheme "$TARGET_NAME" -configuration $CONFIGURATION -sdk iphoneos ONLY_ACTIVE_ARCH=NO ARCHS='arm64 armv7' BUILD_DIR="$BUILD_DIR" BUILD_ROOT="$BUILD_ROOT" ENABLE_BITCODE=YES OTHER_CFLAGS="-fembed-bitcode" BITCODE_GENERATION_MODE=bitcode clean build

xcodebuild -workspace "$WORKSPACE_PATH" -scheme "$TARGET_NAME" -configuration $CONFIGURATION -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6' ONLY_ACTIVE_ARCH=NO ARCHS='i386 x86_64' BUILD_DIR="$BUILD_DIR" BUILD_ROOT="$BUILD_ROOT" ENABLE_BITCODE=YES OTHER_CFLAGS="-fembed-bitcode" BITCODE_GENERATION_MODE=bitcode clean build

框架上传到 cocoapods 成功完成,但是当我在我的项目上安装版本时(构建并运行正常),应用程序在启动时抛出此错误:

dyld: Library not loaded: @rpath/Bolts.framework/Bolts
  Referenced from: /private/var/containers/Bundle/Application/43993CDF-61A7-405F-BA37-6FAD4B8B5FFF/ViewerPro-Demo.app/Frameworks/TiendeoCore.framework/TiendeoCore
  Reason: image not found

我的 podspec 有两个子规范(litefull),我默认安装 lite 版本,但在运行时 TiendeoCore.framworks 抛出需要 full subspec 的依赖,在这种情况下是 Facebook。

在我的代码中,我有一个名为 FULLTIENDEOCORE 的预处理标志来包含使用 full 版本的依赖项的源代码:

#if FULLTIENDEOCORE
import TiendeoAuth
#endif

因此,如果在 OTHER_SWIFT_FLAGS 中声明了标志,那么代码将被执行(此标志被添加到 full 子规范的 podspec 中)。

我不知道我错过了什么。

提前致谢。

【问题讨论】:

这个问题你解决了吗???这正是我们团队遇到的问题。也许您可以分享一些见解?因为我什至无法成功上传 Pod,其中包含已编译的供应商框架的子规范 嗨维克多!我们没有解决这个问题,我们将创建两个单独的目标并生成两个不同的 .framework。我们将为每个子规范指定不同的来源。我们认为您不能为具有不同依赖关系的两个子规范拥有一个 .framework。所以我们将有两个。 我们生成了两个不同的框架,但是我们的主框架不能引用另一个可选框架的代码。我们使用#if canImport()标签,它总是失败...请提供示例,如何我们从主框架中的可选框架访问代码???我们可以在一些私人聊天中聊天吗?这是我的linkedIn:linkedin.com/in/viktor-vostrikov-245975a7 【参考方案1】:

子规范旨在合并,以便消费者可以选择可用子规范的子集。通过对两个 vendored_frameworks 使用相同的名称,很可能引用了错误的名称。

如果这没有帮助,您可能需要调查current open subspec issues。

【讨论】:

您能否分享一个成功将供应商框架包含为子规范的示例? Firebase 将 vendored_framework 包装在另一个 podspec 中,该 podspec 是子规范的依赖项 - github.com/CocoaPods/Specs/blob/master/Specs/0/3/5/Firebase/… 我没有在那个例子中找到 vendored_framework.. 这是我的尝试: mainFramework.subspec 'additionalFramework' do |additionalFramework| additionalFramework.name = "additionalFramework" additionalFramework.vendored_frameworks = "additionalFramework.framework" end 现在我引用一个完全编译的框架,它是可选的。我还可以将 CocoaPods 依赖项添加到“additionalFramework”,还可以直接包含静态框架(我在 *** 中找到了关于它的帖子)mainFramework.static_framework = true我是正确的还是绝对错误的?

以上是关于使用 cocoapods 的子规范构建 ios 框架的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用弱链接的 CocoaPods 库构建 iOS 框架

iOS第三方库管理规范:以Cocoapods为案例

Cocoapods - 找不到 [Github 框架] 的规范

构建 Cordova ios 应用程序是不是总是需要 CocoaPods?

无法在 CocoaPods 中安装 React 子规范

关于 Cocoapods 和 Firebase/Messaging 的 Unity iOS 构建错误