SwiftPackage依赖机制说明.md 5.7 KB

Swift Package 依赖机制说明

🔍 BaseCommon 如何依赖 BaseCore?

关键配置在 BaseCommon/Package.swift

let package = Package(
    name: "BaseCommon",
    // ...
    dependencies: [
        .package(path: "../BaseCore")  // 👈 第1步:声明依赖 BaseCore 包
    ],
    targets: [
        .target(
            name: "BaseCommon",
            dependencies: [
                .product(name: "BaseCore", package: "BaseCore")  // 👈 第2步:在 Target 中使用 BaseCore
            ]
        )
    ]
)

两步配置

第1步:在 dependencies 中声明包依赖

dependencies: [
    .package(path: "../BaseCore")  // 告诉 Swift Package Manager:BaseCommon 依赖 BaseCore 这个包
]

第2步:在 targets 中使用这个包

targets: [
    .target(
        name: "BaseCommon",
        dependencies: [
            .product(name: "BaseCore", package: "BaseCore")  // 告诉编译器:BaseCommon Target 需要使用 BaseCore 这个 product
        ]
    )
]

🔗 传递依赖(Transitive Dependencies)机制

什么是传递依赖?

当 A 依赖 B,B 依赖 C 时,A 会自动获得对 C 的访问权限,这就是传递依赖

实际例子

xdz 项目
  └── 依赖 BaseCommon
        └── 依赖 BaseCore  ✅ (传递依赖)

工作原理

  1. xdz 项目添加 BaseCommon 依赖

    // 在 Xcode 中添加 BaseCommon 包依赖
    
  2. Swift Package Manager 自动解析依赖树

    xdz 需要 BaseCommon
    → 检查 BaseCommon 的 Package.swift
    → 发现 BaseCommon 依赖 BaseCore
    → 自动将 BaseCore 也添加到依赖树中
    
  3. 结果

    • xdz 可以直接使用 BaseCommon
    • xdz 也可以直接使用 BaseCore(因为传递依赖)
    • 不需要手动添加 BaseCore

📝 代码中的体现

BaseCommon 中使用 BaseCore

BaseCommon/Sources/BaseCommon/Common/Network/NetworkHelper.swift 中:

import BaseCore  // ✅ 可以导入,因为 Package.swift 中配置了依赖

public class NetworkHelper {
    // 可以使用 BaseCore 中的类型
    private let networkManager: NetworkManager  // NetworkManager 来自 BaseCore
}

xdz 项目中使用 BaseCommon(自动包含 BaseCore)

xdz/xdz/xdzApp.swift 中:

import BaseCommon  // ✅ 导入 BaseCommon

// 因为传递依赖,BaseCore 也被自动引入了
// 所以可以直接使用 BaseCore 的类型(如果需要)
import BaseCore    // ✅ 可选,因为已经通过 BaseCommon 传递了

🎯 完整依赖链示例

场景:xdz 项目使用 BaseCommon 的 NetworkHelper

// xdz/xdz/SomeFile.swift
import BaseCommon  // 只导入 BaseCommon

func someFunction() {
    // 使用 BaseCommon 的 NetworkHelper
    let helper = NetworkHelper.shared  // ✅ 来自 BaseCommon
    
    // NetworkHelper 内部使用了 BaseCore 的 NetworkManager
    // 虽然我们没有直接 import BaseCore,但传递依赖让它可用
}

依赖解析过程

1. xdz 导入 BaseCommon
   ↓
2. Swift Package Manager 检查 BaseCommon 的依赖
   ↓
3. 发现 BaseCommon 依赖 BaseCore
   ↓
4. 自动将 BaseCore 添加到编译依赖中
   ↓
5. xdz 可以访问 BaseCommon 和 BaseCore

🔧 验证传递依赖

方法 1:查看依赖树

在终端运行:

cd xdz_ios/xdz
swift package show-dependencies  # 如果项目支持 SPM

方法 2:在 Xcode 中查看

  1. 选择项目 xdz
  2. 选择 Target xdz
  3. 点击 "Build Phases" 标签
  4. 展开 "Link Binary With Libraries"
  5. 你会看到:
    • BaseCommon.framework ✅
    • BaseCore.framework ✅ (自动传递)

方法 3:代码验证

xdz/xdz/xdzApp.swift 中:

import SwiftUI
import BaseCommon  // 只导入 BaseCommon

@main
struct xdzApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
    
    init() {
        // 测试:使用 BaseCommon(需要 BaseCore)
        let helper = NetworkHelper.shared  // ✅ 来自 BaseCommon
        // NetworkHelper 内部使用了 BaseCore,但不需要直接导入
    }
}

如果编译通过,说明传递依赖正常工作!

📊 依赖关系图

┌─────────────┐
│   BaseCore  │  (基础层,不依赖其他)
└──────┬──────┘
       │
       │ 依赖
       │
┌──────▼──────────┐
│   BaseCommon    │  (依赖 BaseCore)
└──────┬──────────┘
       │
       │ 依赖(传递)
       │
┌──────▼──────────┐
│  CapabilityPush │  (依赖 BaseCore)
└──────┬──────────┘
       │
       │ 依赖(传递)
       │
┌──────▼──────┐
│     xdz     │  (业务项目)
│             │  - 依赖 BaseCommon → 自动获得 BaseCore ✅
│             │  - 依赖 CapabilityPush → 自动获得 BaseCore ✅
└─────────────┘

💡 关键点总结

  1. Package.swift 中的 dependencies:声明包级别的依赖
  2. Package.swift 中的 targets[].dependencies:声明 Target 级别的依赖
  3. 传递依赖:Swift Package Manager 自动处理,无需手动配置
  4. xdz 项目:只需要添加 BaseCommon 和 CapabilityPush,BaseCore 会自动传递

🎓 类比理解

就像:

  • 你买了一本书(BaseCommon)
  • 这本书引用了另一本书(BaseCore)
  • 当你使用这本书时,你自动获得了引用书的访问权限
  • 不需要单独购买引用书(不需要单独添加 BaseCore)