在同一工作区的 iOS 框架和应用程序项目中使用 Cocoapods

问题描述 投票:0回答:2

好吧,也许我做的事情完全错误,所以请随时纠正我。让我解释一下我想要实现的目标。

我从事一个具有多个目标的项目。每个目标都用于创建一个单独的应用程序。这些目标共享许多核心功能,但某些目标添加了一些额外的代码或仅使用“核心”的最小集(例如一些 Web 服务)。

目前所有内容都打包到一个 Xcode 项目中,我使用“目标成员资格”功能(在文件检查器中)来标记哪个类属于哪个目标。核心类是所有目标的成员,特殊类仅是一个目标的成员。

这很容易让人困惑,并带来另一个问题。我想使用 CI/CD 服务器自动构建和发布 Test Flight 的更新。由于目前所有文件都在一个存储库中,因此我无法自动检测哪个应用程序需要更新。

我现在的计划是将我的存储库和项目分成多个部分。我考虑使用一个“核心”项目以及每个应用程序的一个项目。每个项目都将驻留在其自己的 GIT 存储库中。

然后我创建一个“主”存储库并使用 GIT 子树添加其他存储库。然后,我可以分别为每个存储库设置触发器来构建相应的应用程序(或者如果我更改核心中的某些内容,则立即构建所有应用程序)。

到目前为止,结构看起来不错,但我在正确设置 cocoapods 时遇到问题。我的问题是我在我的核心中使用了 cocoapod 依赖项,它现在是一个框架。我的 Podfile 目前看起来像这样:

source 'https://github.com/CocoaPods/Specs.git'
workspace 'Master.xcworkspace'

platform :ios, '10.0'
use_frameworks!

project 'core/Core'
project 'app/MyApp'

def common_pods
    pod 'Firebase/Core'
    pod 'Alamofire'
end

target 'Core' do
  project 'core/Core'
  common_pods  

  target 'CoreTests' do
    inherit! :search_paths
  end
end

target 'MyApp' do
  project 'app/MyApp'
end

我的文件系统看起来像这样:

  • 主控(文件夹)
    • Master.xcworkspace
    • Podfile
    • 核心(文件夹)
      • Core.xcproject
      • Core(包含文件的文件夹)
    • 应用程序(文件夹)
      • MyApp.xcproject
      • MyApp(包含文件的文件夹)

如果我现在在 MyApp 类之一中导入 Core 框架,我会收到一个构建错误,提示“缺少必需的模块‘Firebase’”,如果我将“common_pods”添加到 MyApp 目标,我可以构建,但在运行时会得到一堆“Class xxx 在 Core.framework 和 /.../MyApp.app/MyApp 中均实现。将使用两者之一。哪个未定义。”错误,我的应用程序崩溃了。

我曾经读到,应该制作自定义框架 pod 并使用 cocoapods 来添加它们,而不是直接通过项目目标嵌入二进制文件功能添加它们,但这是否意味着每次我对核心进行更改时,我都需要构建框架,然后在最终构建和运行我的应用程序之前进行 Pod 更新?那不可能是解决方案。

我错过了什么?我做错了什么?希望你能帮我解答一下。

ios xcode git frameworks cocoapods
2个回答
3
投票

在将我的应用程序拆分为框架时,我遇到了类似的问题。每个单独的目标都必须包含其使用的 pod 的自己的副本。 Pod 不在目标之间共享。 http://samwize.com/2015/01/26/projects-workspace-embedded-framework-and-cocoapods/

common_pods
添加到 podfile 中的“MyApp”目标,正如您尝试为我工作的那样,这让我相信您的问题可能是如何将框架项目添加到工作区。我按照此处的说明进行操作:http://www.splinter.com.au/2016/11/22/scalable-swift/

我的理解是您正在寻找的行为,链接到 Core 框架也将链接到 Core 框架的 pod 依赖项,只有当您将 Core 框架放入它自己的 pod 中时才有可能 - 但正如您所指出的,有相当多的问题这样做会产生一些开销。

希望 Swift 包管理器有一天能让这变得更容易:)


0
投票

解决方案是仅在 Core 中添加 pods 依赖项并将导入设为私有,您还需要在

pod install
之后调整生成的文件,因为 pods 很简单,如果看到 Xcode 框架,则将额外的 pods 作为依赖项添加到主目标中取决于它。

步骤:

  • 不要在主应用程序中使用
    Firebase
    (仅在Core中) - 似乎你已经这样做了;
  • 在 Core 中标记所有
    import Firebase
    ,如下所示:
@_implementationOnly
import Firebase
  • 请勿将
    common_pods
    添加到
    Podfile
    中的主应用程序中(如您最初设置的那样)
  • 向您的 Podfile 添加补丁:
load 'Podfile.RemoveDuplicates.rb'

post_install do |installer|
  remove_duplicated_libraries('Pods-MyApp', 'Pods-Core', installer)
end
  • 添加文件
    Podfile.RemoveDuplicates.rb
def remove_duplicated_libraries(app_pod_name, kit_pod_name, installer)
  app_target = installer.aggregate_targets.find { |x| x.name == app_pod_name }
  kit_target = installer.aggregate_targets.find { |x| x.name == kit_pod_name }

  app_target.xcconfigs.each do |config_name, config_file|
      get_libraries_names(kit_target)
      .each { |library|
          config_file.libraries.delete(library)
          config_file.frameworks.delete(library)
      }

      xcconfig_path = app_target.xcconfig_path(config_name)
      config_file.save_as(xcconfig_path)
  end
end

def get_libraries_names(pod_target)
  libraryNames = pod_target.specs.flat_map do |spec|
      frameworkPaths = unless spec.attributes_hash['ios'].nil?
          then spec.attributes_hash['ios']['vendored_frameworks']
          else spec.attributes_hash['vendored_frameworks']
      end || [spec.name.split(/\//, 2).first]

      map_paths_to_filenames(frameworkPaths)
  end

  libraryNames.uniq
end

def map_paths_to_filenames(paths)
  Array(paths).map(&:to_s).map do |filename|
      extension = File.extname filename
      File.basename filename, extension
  end
end
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.