A modern macOS application using a workspace + SPM package architecture for clean separation between app shell and feature code.
SpeechToText/
├── SpeechToText.xcworkspace/ # Open this file in Xcode
├── SpeechToText.xcodeproj/ # App shell project
├── SpeechToText/ # App target (minimal)
│ ├── Assets.xcassets/ # App-level assets (icons, colors)
│ ├── SpeechToTextApp.swift # App entry point
│ ├── SpeechToText.entitlements # App sandbox settings
│ └── SpeechToText.xctestplan # Test configuration
├── SpeechToTextPackage/ # 🚀 Primary development area
│ ├── Package.swift # Package configuration
│ ├── Sources/SpeechToTextFeature/ # Your feature code
│ └── Tests/SpeechToTextFeatureTests/ # Unit tests
└── SpeechToTextUITests/ # UI automation tests
- App Shell:
SpeechToText/contains minimal app lifecycle code - Feature Code:
SpeechToTextPackage/Sources/SpeechToTextFeature/is where most development happens - Separation: Business logic lives in the SPM package, app target just imports and displays it
- Files added to the filesystem automatically appear in Xcode
- No need to manually add files to project targets
- Reduces project file conflicts in teams
The app is sandboxed by default with basic file access permissions. Modify SpeechToText.entitlements to add capabilities as needed.
Most development happens in SpeechToTextPackage/Sources/SpeechToTextFeature/ - organize your code as you prefer.
Types exposed to the app target need public access:
public struct SettingsView: View {
public init() {}
public var body: some View {
// Your view code
}
}Edit SpeechToTextPackage/Package.swift to add SPM dependencies:
dependencies: [
.package(url: "https://github.com/example/SomePackage", from: "1.0.0")
],
targets: [
.target(
name: "SpeechToTextFeature",
dependencies: ["SomePackage"]
),
]- Unit Tests:
SpeechToTextPackage/Tests/SpeechToTextFeatureTests/(Swift Testing framework) - UI Tests:
SpeechToTextUITests/(XCUITest framework) - Test Plan:
SpeechToText.xctestplancoordinates all tests
Build settings are managed through XCConfig files in Config/:
Config/Shared.xcconfig- Common settings (bundle ID, versions, deployment target)Config/Debug.xcconfig- Debug-specific settingsConfig/Release.xcconfig- Release-specific settingsConfig/Tests.xcconfig- Test-specific settings
The app is sandboxed by default with basic file access. Edit SpeechToText/SpeechToText.entitlements to add capabilities:
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<!-- Add other entitlements as needed -->Add multiple windows and settings panels:
@main
struct SpeechToTextApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
Settings {
SettingsView()
}
}
}- App-Level Assets:
SpeechToText/Assets.xcassets/(app icon with multiple sizes, accent color) - Feature Assets: Add
Resources/folder to SPM package if needed
To include assets in your feature package:
.target(
name: "SpeechToTextFeature",
dependencies: [],
resources: [.process("Resources")]
)This project was scaffolded using XcodeBuildMCP, which provides tools for AI-assisted macOS development workflows.