Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
import Foundation
|
|
|
|
|
import Photos
|
|
|
|
|
|
perf: move heavy work off main actor, throttle progress updates, add signposts
BackupEngine:
- fetchAssets() runs in Task.detached — prevents 100-500ms UI freeze during
PHFetchResult enumeration on large libraries
- Manifest JSON decode + ManifestIndex Set construction run in Task.detached
- pendingAssets filter runs in Task.detached — O(N) array filter off main thread
- Progress updates throttled to 8 Hz via ProgressThrottle — eliminates the
continuous SwiftUI full-tree redraws caused by per-byte upload callbacks
- bytesSoFar captured by value in upload closure — avoids mutable var capture
- reserveCapacity on manifestEntries array
- os_signpost intervals on FetchAssets, NASConnect, ManifestLoad,
BuildPendingQueue, UploadLoop, UploadFile for Instruments profiling
BackupStatusService:
- countSafe() marked nonisolated — runs in Task.detached off main actor,
keeping touch/animation responsive during PHFetchResult batch enumeration
- ManifestIndex JSON decode + Set construction run in Task.detached
- Bootstrap ManifestIndex(nasListing:) construction off main actor
- writeManifest JSON decode/encode/merge off main actor
- os_signpost intervals on Reconcile, ManifestLoad, CountSafe
Model types:
- ManifestIndex, ManifestEntry, PhotoAsset, BackupFilter marked Sendable —
safe to pass across task boundaries without warnings
Co-Authored-By: Kutesir <kutesir@provoc.ug>
Co-Authored-By: Sentry <sentry@provoc.ug>
2026-05-17 16:42:48 +03:00
|
|
|
struct PhotoAsset: Sendable {
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
let localIdentifier: String
|
|
|
|
|
let filename: String
|
|
|
|
|
let creationDate: Date?
|
|
|
|
|
let mediaType: PHAssetMediaType
|
|
|
|
|
let pixelWidth: Int
|
|
|
|
|
let pixelHeight: Int
|
|
|
|
|
let duration: TimeInterval
|
|
|
|
|
let isScreenshot: Bool
|
|
|
|
|
let isRAW: Bool
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protocol PhotoLibraryProtocol: AnyObject {
|
|
|
|
|
var authorizationStatus: PHAuthorizationStatus { get }
|
|
|
|
|
func requestAuthorization() async -> PHAuthorizationStatus
|
|
|
|
|
func fetchAssets(filter: BackupFilter) -> [PhotoAsset]
|
|
|
|
|
func exportAsset(_ asset: PhotoAsset) async throws -> URL
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-18 23:15:51 +03:00
|
|
|
struct BackupFilter: Codable, Sendable, Equatable {
|
Initial scaffold — NASBackup iOS app
Full project scaffold: XcodeGen project.yml, Core models/protocols/errors,
SMBService (kishikawakatsumi/SMBClient), SFTPService (Citadel 0.9.2),
PhotoLibraryService, LANMonitor, BackupEngine, BackgroundTaskManager,
all feature UIs (Login, Connect, Browse, Backup, History, Settings),
Shared components and theme. Builds clean with zero errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:04 +03:00
|
|
|
var includePhotos: Bool = true
|
|
|
|
|
var includeVideos: Bool = true
|
|
|
|
|
var includeScreenshots: Bool = false
|
|
|
|
|
var includeRAW: Bool = false
|
|
|
|
|
var newFilesOnly: Bool = true
|
|
|
|
|
}
|