Microapps architecture splits an app into one Swift Package Manager module per feature, so Xcode recompiles only changed modules and each feature can run as its own app. This first part sets up the package that holds every module.
One Package, Many Modules
Create one Swift package (File -> New -> Package, for example MyAppLibrary) in the project
root and add it to the app project. All modules live in it, so the watch app or a widget can
depend on just the modules it needs instead of the whole codebase. The package has no project
file: the folder structure under Sources/ and Tests/ is the structure.
Package.swift Declares the Modules
import PackageDescription
let package = Package(
name: "MyAppLibrary",
platforms: [.iOS(.v15)],
products: [
.library(name: "DesignSystem", targets: ["DesignSystem"])
],
dependencies: [
.package(url: "https://github.com/mecid/SwiftUICharts", from: "0.6.3")
],
targets: [
.target(name: "DesignSystem", dependencies: ["SwiftUICharts"]),
.testTarget(name: "DesignSystemTests", dependencies: ["DesignSystem"]),
]
)
The parts: platforms sets the supported OS versions, products lists what other projects can
import, dependencies lists external packages, and targets are the modules the compiler
builds independently. A module is just a folder in Sources/ whose name matches its target;
tests go in a matching folder under Tests/.
Public Is the Module Boundary
Swift defaults to internal, which keeps code invisible outside its module. Mark exactly the
types and functions a module means to expose with public; everything else stays private to the
module, which makes the boundary explicit.
import SwiftUI
public struct MainButtonStyle: PrimitiveButtonStyle {
public func makeBody(configuration: Configuration) -> some View {
Button(configuration)
.controlSize(.large)
.buttonStyle(.borderedProminent)
}
}
extension PrimitiveButtonStyle where Self == MainButtonStyle {
public static var main: Self { .init() }
}
Add the DesignSystem library under the app target's Frameworks, Libraries, and Embedded
Content to import it. Later parts of the series cover feature modules, resources and
localization, and dependency injection.