好吧,也许我做的事情完全错误,所以请随时纠正我。让我解释一下我想要实现的目标。
我从事一个具有多个目标的项目。每个目标都用于创建一个单独的应用程序。这些目标共享许多核心功能,但某些目标添加了一些额外的代码或仅使用“核心”的最小集(例如一些 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
我的文件系统看起来像这样:
如果我现在在 MyApp 类之一中导入 Core 框架,我会收到一个构建错误,提示“缺少必需的模块‘Firebase’”,如果我将“common_pods”添加到 MyApp 目标,我可以构建,但在运行时会得到一堆“Class xxx 在 Core.framework 和 /.../MyApp.app/MyApp 中均实现。将使用两者之一。哪个未定义。”错误,我的应用程序崩溃了。
我曾经读到,应该制作自定义框架 pod 并使用 cocoapods 来添加它们,而不是直接通过项目目标嵌入二进制文件功能添加它们,但这是否意味着每次我对核心进行更改时,我都需要构建框架,然后在最终构建和运行我的应用程序之前进行 Pod 更新?那不可能是解决方案。
我错过了什么?我做错了什么?希望你能帮我解答一下。
在将我的应用程序拆分为框架时,我遇到了类似的问题。每个单独的目标都必须包含其使用的 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 包管理器有一天能让这变得更容易:)
解决方案是仅在 Core 中添加 pods 依赖项并将导入设为私有,您还需要在
pod install
之后调整生成的文件,因为 pods 很简单,如果看到 Xcode 框架,则将额外的 pods 作为依赖项添加到主目标中取决于它。
步骤:
Firebase
(仅在Core中) - 似乎你已经这样做了;import Firebase
,如下所示:@_implementationOnly
import Firebase
common_pods
添加到 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