IndieAbout: About section in iOS Settings and macOS About window; LICENSE
switched to the portfolio-standard ISC text (reflowed for in-app rendering).
IndieBackup: files-only backup/restore of the iCloud container documents
('.notesbackup' document type on both platforms), SwiftData cache rebuilt
via SyncEngine.rebuildCache() after restore, monitors suspended during the
file swap, onOpenURL import with pre-launch queueing.
Release pipeline: Scripts/release.sh (ios|mac|all) archives and uploads via
xcodebuild + ASC API key; platform-partitioned build numbers (iOS even,
macOS odd) since both targets share one bundle ID and build sequence.
35 lines
1.1 KiB
Swift
35 lines
1.1 KiB
Swift
import Foundation
|
|
import IndieBackup
|
|
import SwiftData
|
|
|
|
/// Owns all service objects; created asynchronously at launch and injected
|
|
/// into the SwiftUI environment.
|
|
@Observable
|
|
@MainActor
|
|
final class AppServices {
|
|
let modelContainer: ModelContainer
|
|
let syncEngine: SyncEngine
|
|
let contextService: ContextService
|
|
let backupController: BackupController
|
|
|
|
init() async {
|
|
let container = NotesModelContainer.make()
|
|
self.modelContainer = container
|
|
let engine = SyncEngine(modelContainer: container)
|
|
self.syncEngine = engine
|
|
self.contextService = ContextService()
|
|
self.backupController = BackupController(
|
|
configuration: NotesBackupConfiguration(syncEngine: engine)
|
|
)
|
|
}
|
|
|
|
/// The file extension this app owns for backup documents. Used to route
|
|
/// `onOpenURL` imports to a restore.
|
|
var backupFileExtension: String { backupController.configuration.backupFileExtension }
|
|
|
|
/// Slow startup work (iCloud container discovery) — runs after the UI is up.
|
|
func startDeferredServices() async {
|
|
await syncEngine.connect()
|
|
}
|
|
}
|