创建包含依赖项的 .xcframework

huangapple go评论57阅读模式
英文:

Create .xcframework with dependencies

问题

我正在尝试为客户基于我的自有代码创建一个自定义的Swift xcframework "FrameworkA",该代码依赖于另一个第三方框架 "FrameworkB"(通过SPM集成)。我在弄清楚最佳方法时遇到了困难。

在我的情况下,我的项目中已经有多个目标,并且我已经为 "FrameworkA" 添加了另一个目标,并将相关文件添加到了框架目标中。

如果我将 "FrameworkB" 添加到我的框架目标的 "框架和库" 部分,并在代码中添加它,我可以使我的新框架构建。

import FrameworkB 

let frameworkKit = FrameworkKit()

然而,当我阅读关于 "伞形框架" 的信息时,答案在这里列出苹果的文档建议我 不应该 将一个框架包含在另一个框架中。

那么,有哪些具体的方法可以实现这一点呢?我无法排除这个依赖,因为没有它,我的框架根本无法构建。

英文:

I am trying to create a custom Swift xcframework "FrameworkA" for a client based on my own code, which has a dependency to another 3rd party framework "FrameworkB" (which I integrate through SPM). I'm having trouble figuring out the best way to do this.

In my case, I already have multiple targets in my project, and I have added another one for "FrameworkA", and added the relevant files to the framework target.

I can get my new framework to build if I add "FrameworkB" to "Framework and Libraries" section for my framework target, and adding it in code.

import FrameworkB 

let frameworkKit = FrameworkKit()

Now, referencing Apple's documentation, I used xcodebuild archive to create archive files for both "iOS" and "iOS Simulator".

However, when I read about 'umbrella frameworks', the answer listed here and Apple's documentation suggests that I shouldn't include a framework inside another framework.

So what are the concrete ways to accomplish this? I can't exclude the dependency because without it, my framework won't build at all.

答案1

得分: 1

创建自定义的Swift xcframework并依赖于第三方框架时,有几种方法可以确保正确集成而不违反最佳实践。以下是一些具体的方法:

  1. 将FrameworkB嵌入为二进制文件:不要将FrameworkB作为一个框架包含在FrameworkA内,而是将FrameworkB嵌入为FrameworkA xcframework中的二进制文件。这样,FrameworkB不会被视为FrameworkA内的框架,而是作为一个二进制依赖项。要实现这一点,请按照以下步骤操作:

    • 分别构建FrameworkB并获取二进制文件(例如,FrameworkB.framework)。
    • 通过将其拖放到项目导航器中,将二进制文件添加到FrameworkA项目中。
    • 在FrameworkA的项目设置中,导航到目标的设置,转到“Build Phases”选项卡,在“Embed Frameworks”下添加FrameworkB的二进制文件。
    • 在您的代码中,您可以继续导入并使用FrameworkB。

    这种方法避免了将一个框架包含在另一个框架内可能出现的问题。

  2. 指定FrameworkB为传递性依赖项:如果您使用Swift Package Manager(SPM)来管理依赖关系,您可以在您的Package.swift文件中将FrameworkB指定为FrameworkA的依赖项。这样,当您构建或使用FrameworkA时,SPM将自动处理依赖关系解析并为您包含FrameworkB。以下是如何在Package.swift中指定依赖项的示例:

    let package = Package(
        name: "FrameworkA",
        products: [
            .library(
                name: "FrameworkA",
                targets: ["FrameworkA"]
            ),
        ],
        dependencies: [
            .package(url: "https://github.com/vendor/FrameworkB", .upToNextMajor(from: "1.0.0")),
        ],
        targets: [
            .target(
                name: "FrameworkA",
                dependencies: [
                    .product(name: "FrameworkB", package: "FrameworkB"),
                ]
            ),
        ]
    )
    

    使用此设置,当您构建FrameworkA时,SPM将自动获取并包含FrameworkB作为依赖项。

  3. 将FrameworkB文档化为先决条件:如果FrameworkB是一个独立的框架,需要与FrameworkA一起存在,您可以将其文档化为先决条件。在文档中,提供明确的说明,说明在集成FrameworkA之前如何获取和包含FrameworkB。这样,FrameworkA的消费者将意识到依赖关系,并可以单独处理其集成。

选择最适合您的要求和项目结构的方法。通常,嵌入二进制文件或使用SPM进行传递性依赖管理是首选,以避免与将框架包含在其他框架内相关的问题。

英文:

When creating a custom Swift xcframework that has a dependency on a third-party framework, there are a few approaches you can take to ensure the proper integration without violating best practices. Here are some concrete ways to accomplish this:

  1. Embed FrameworkB as a binary: Instead of including FrameworkB inside FrameworkA as a framework, you can embed FrameworkB as a binary in your FrameworkA xcframework. This way, FrameworkB is not treated as a framework within FrameworkA but rather as a binary dependency. To achieve this, follow these steps:

    • Build FrameworkB separately and obtain the binary file (e.g., FrameworkB.framework).
    • Add the binary to your FrameworkA project by dragging it into the project navigator.
    • In the project settings for FrameworkA, navigate to the target's settings, go to the "Build Phases" tab, and under "Embed Frameworks," add the FrameworkB binary.
    • In your code, you can continue to import and use FrameworkB.

    This approach avoids the potential issues associated with including one framework inside another.

  2. Specify FrameworkB as a transitive dependency: If you're using Swift Package Manager (SPM) to manage dependencies, you can specify FrameworkB as a dependency of FrameworkA in your Package.swift file. This way, when you build or use FrameworkA, SPM will automatically handle the dependency resolution and include FrameworkB for you. Here's an example of how you can specify the dependency in your Package.swift:

    let package = Package(
        name: "FrameworkA",
        products: [
            .library(
                name: "FrameworkA",
                targets: ["FrameworkA"]
            ),
        ],
        dependencies: [
            .package(url: "https://github.com/vendor/FrameworkB", .upToNextMajor(from: "1.0.0")),
        ],
        targets: [
            .target(
                name: "FrameworkA",
                dependencies: [
                    .product(name: "FrameworkB", package: "FrameworkB"),
                ]
            ),
        ]
    )
    

    With this setup, when you build FrameworkA, SPM will automatically fetch and include FrameworkB as a dependency.

  3. Document FrameworkB as a prerequisite: If FrameworkB is a separate framework that needs to be present alongside FrameworkA, you can document it as a prerequisite. In your documentation, provide clear instructions on how to obtain and include FrameworkB before integrating FrameworkA. This way, consumers of FrameworkA will be aware of the dependency and can handle its integration separately.

Choose the approach that best fits your requirements and project structure. Embedding the binary or using SPM for transitive dependency management are generally preferred to avoid issues related to including frameworks inside other frameworks.

huangapple
  • 本文由 发表于 2023年5月28日 02:58:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76348544.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定