Remove all @Attribute annotations and use simple var with defaults. The @Attribute annotations were causing SwiftData's @Model macro to generate incorrect type mappings. Simple var declarations with default values let SwiftData's type inference work correctly without explicit attribute directives. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@@ -2,28 +2,23 @@ import Foundation |
||
| 2 | 2 |
import SwiftData |
| 3 | 3 |
|
| 4 | 4 |
@Model final class AnomalyRecord {
|
| 5 |
- @Attribute(.unique) var id: UUID |
|
| 6 |
- @Attribute var detectedAt: Date |
|
| 7 |
- @Attribute var snapshotID: UUID |
|
| 8 |
- @Attribute var deltaID: UUID? |
|
| 9 |
- @Attribute var deviceID: String |
|
| 10 |
- @Attribute var anomalyTypeRaw: String |
|
| 11 |
- @Attribute var severityRaw: String |
|
| 12 |
- @Attribute var typeIdentifier: String? |
|
| 13 |
- @Attribute var message: String |
|
| 14 |
- @Attribute var isResolved: Bool |
|
| 5 |
+ var id: UUID = UUID() |
|
| 6 |
+ var detectedAt: Date = Date.now |
|
| 7 |
+ var snapshotID: UUID = UUID() |
|
| 8 |
+ var deltaID: UUID? |
|
| 9 |
+ var deviceID: String = "" |
|
| 10 |
+ var anomalyTypeRaw: String = AnomalyType.deletion.rawValue |
|
| 11 |
+ var severityRaw: String = Severity.info.rawValue |
|
| 12 |
+ var typeIdentifier: String? |
|
| 13 |
+ var message: String = "" |
|
| 14 |
+ var isResolved: Bool = false |
|
| 15 | 15 |
|
| 16 | 16 |
init(snapshotID: UUID, deviceID: String, anomalyType: AnomalyType, severity: Severity) {
|
| 17 | 17 |
self.id = UUID() |
| 18 |
- self.detectedAt = Date.now |
|
| 19 | 18 |
self.snapshotID = snapshotID |
| 20 |
- self.deltaID = nil |
|
| 21 | 19 |
self.deviceID = deviceID |
| 22 | 20 |
self.anomalyTypeRaw = anomalyType.rawValue |
| 23 | 21 |
self.severityRaw = severity.rawValue |
| 24 |
- self.typeIdentifier = nil |
|
| 25 |
- self.message = "" |
|
| 26 |
- self.isResolved = false |
|
| 27 | 22 |
} |
| 28 | 23 |
} |
| 29 | 24 |
|
@@ -1,15 +1,12 @@ |
||
| 1 | 1 |
import Foundation |
| 2 | 2 |
import SwiftData |
| 3 | 3 |
|
| 4 |
-@Model |
|
| 5 |
-final class DeviceProfile {
|
|
| 6 |
- @Attribute(.unique) var deviceID: String |
|
| 7 |
- @Attribute var name: String |
|
| 8 |
- @Attribute var colorTag: String |
|
| 4 |
+@Model final class DeviceProfile {
|
|
| 5 |
+ var deviceID: String = "" |
|
| 6 |
+ var name: String = "" |
|
| 7 |
+ var colorTag: String = "blue" |
|
| 9 | 8 |
|
| 10 | 9 |
init(deviceID: String) {
|
| 11 | 10 |
self.deviceID = deviceID |
| 12 |
- self.name = "" |
|
| 13 |
- self.colorTag = "blue" |
|
| 14 | 11 |
} |
| 15 | 12 |
} |
@@ -1,57 +1,36 @@ |
||
| 1 | 1 |
import Foundation |
| 2 | 2 |
import SwiftData |
| 3 | 3 |
|
| 4 |
-@Model |
|
| 5 |
-final class HealthSnapshot {
|
|
| 6 |
- @Attribute(.unique) var id: UUID |
|
| 7 |
- @Attribute var timestamp: Date |
|
| 8 |
- @Attribute var osVersion: String |
|
| 9 |
- @Attribute var deviceName: String |
|
| 10 |
- @Attribute var deviceID: String |
|
| 11 |
- @Attribute var localSequenceNumber: Int |
|
| 12 |
- @Attribute var previousSnapshotID: UUID? |
|
| 13 |
- @Attribute var isChainStart: Bool |
|
| 14 |
- @Attribute var recoveredDeviceID: Bool |
|
| 15 |
- @Attribute var snapshotQuality: SnapshotQuality |
|
| 16 |
- @Attribute var anomalyFlagsJSON: String |
|
| 17 |
- @Attribute var triggerReason: String |
|
| 18 |
- @Attribute var isPostRestore: Bool |
|
| 19 |
- @Attribute var isPostRestoreInferred: Bool |
|
| 20 |
- @Attribute var isPostRestoreSuppressedDeltaID: UUID? |
|
| 21 |
- @Attribute var hardwareModel: String |
|
| 22 |
- @Attribute var appBuildVersion: String |
|
| 23 |
- @Attribute var monitoredTypeSetHash: String |
|
| 24 |
- @Attribute var monitoredRegistryVersion: Int |
|
| 25 |
- @Attribute var yearlyCountTimezoneIdentifier: String |
|
| 4 |
+@Model final class HealthSnapshot {
|
|
| 5 |
+ var id: UUID = UUID() |
|
| 6 |
+ var timestamp: Date = Date.now |
|
| 7 |
+ var osVersion: String = "" |
|
| 8 |
+ var deviceName: String = "" |
|
| 9 |
+ var deviceID: String = "" |
|
| 10 |
+ var localSequenceNumber: Int = 0 |
|
| 11 |
+ var previousSnapshotID: UUID? |
|
| 12 |
+ var isChainStart: Bool = false |
|
| 13 |
+ var recoveredDeviceID: Bool = false |
|
| 14 |
+ var snapshotQuality: SnapshotQuality = .complete |
|
| 15 |
+ var anomalyFlagsJSON: String = "[]" |
|
| 16 |
+ var triggerReason: String = "manual" |
|
| 17 |
+ var isPostRestore: Bool = false |
|
| 18 |
+ var isPostRestoreInferred: Bool = false |
|
| 19 |
+ var isPostRestoreSuppressedDeltaID: UUID? |
|
| 20 |
+ var hardwareModel: String = "" |
|
| 21 |
+ var appBuildVersion: String = "" |
|
| 22 |
+ var monitoredTypeSetHash: String = "" |
|
| 23 |
+ var monitoredRegistryVersion: Int = 0 |
|
| 24 |
+ var yearlyCountTimezoneIdentifier: String = "" |
|
| 26 | 25 |
@Relationship(deleteRule: .cascade, inverse: \TypeCount.snapshot) |
| 27 |
- var typeCounts: [TypeCount]? |
|
| 26 |
+ var typeCounts: [TypeCount]? = [] |
|
| 28 | 27 |
|
| 29 |
- init( |
|
| 30 |
- timestamp: Date, |
|
| 31 |
- osVersion: String, |
|
| 32 |
- deviceName: String, |
|
| 33 |
- deviceID: String |
|
| 34 |
- ) {
|
|
| 28 |
+ init(timestamp: Date, osVersion: String, deviceName: String, deviceID: String) {
|
|
| 35 | 29 |
self.id = UUID() |
| 36 | 30 |
self.timestamp = timestamp |
| 37 | 31 |
self.osVersion = osVersion |
| 38 | 32 |
self.deviceName = deviceName |
| 39 | 33 |
self.deviceID = deviceID |
| 40 |
- self.localSequenceNumber = 0 |
|
| 41 |
- self.previousSnapshotID = nil |
|
| 42 |
- self.isChainStart = false |
|
| 43 |
- self.recoveredDeviceID = false |
|
| 44 |
- self.snapshotQuality = .complete |
|
| 45 |
- self.anomalyFlagsJSON = "[]" |
|
| 46 |
- self.triggerReason = "manual" |
|
| 47 |
- self.isPostRestore = false |
|
| 48 |
- self.isPostRestoreInferred = false |
|
| 49 |
- self.isPostRestoreSuppressedDeltaID = nil |
|
| 50 |
- self.hardwareModel = "" |
|
| 51 |
- self.appBuildVersion = "" |
|
| 52 |
- self.monitoredTypeSetHash = "" |
|
| 53 |
- self.monitoredRegistryVersion = 0 |
|
| 54 |
- self.yearlyCountTimezoneIdentifier = "" |
|
| 55 | 34 |
self.typeCounts = [] |
| 56 | 35 |
} |
| 57 | 36 |
} |
@@ -2,19 +2,17 @@ import Foundation |
||
| 2 | 2 |
import SwiftData |
| 3 | 3 |
|
| 4 | 4 |
@Model final class OperationLog {
|
| 5 |
- @Attribute(.unique) var id: UUID |
|
| 6 |
- @Attribute var timestamp: Date |
|
| 7 |
- @Attribute var operationType: String |
|
| 8 |
- @Attribute var affectedSnapshotIDsJSON: String |
|
| 9 |
- @Attribute var summary: String |
|
| 10 |
- @Attribute var operationDeviceID: String |
|
| 11 |
- @Attribute var operationAppBuildVersion: String |
|
| 5 |
+ var id: UUID = UUID() |
|
| 6 |
+ var timestamp: Date = Date.now |
|
| 7 |
+ var operationType: String = "" |
|
| 8 |
+ var affectedSnapshotIDsJSON: String = "[]" |
|
| 9 |
+ var summary: String = "" |
|
| 10 |
+ var operationDeviceID: String = "" |
|
| 11 |
+ var operationAppBuildVersion: String = "" |
|
| 12 | 12 |
|
| 13 | 13 |
init(operationType: String, summary: String, deviceID: String, appBuildVersion: String) {
|
| 14 | 14 |
self.id = UUID() |
| 15 |
- self.timestamp = Date.now |
|
| 16 | 15 |
self.operationType = operationType |
| 17 |
- self.affectedSnapshotIDsJSON = "[]" |
|
| 18 | 16 |
self.summary = summary |
| 19 | 17 |
self.operationDeviceID = deviceID |
| 20 | 18 |
self.operationAppBuildVersion = appBuildVersion |
@@ -2,26 +2,21 @@ import Foundation |
||
| 2 | 2 |
import SwiftData |
| 3 | 3 |
|
| 4 | 4 |
@Model final class SnapshotDelta {
|
| 5 |
- @Attribute(.unique) var id: UUID |
|
| 6 |
- @Attribute var fromSnapshotID: UUID |
|
| 7 |
- @Attribute var toSnapshotID: UUID |
|
| 8 |
- @Attribute var deviceID: String |
|
| 9 |
- @Attribute var computedAt: Date |
|
| 10 |
- @Attribute var checksumBefore: String |
|
| 11 |
- @Attribute var checksumAfter: String |
|
| 12 |
- @Attribute var isCloudKitImported: Bool |
|
| 5 |
+ var id: UUID = UUID() |
|
| 6 |
+ var fromSnapshotID: UUID = UUID() |
|
| 7 |
+ var toSnapshotID: UUID = UUID() |
|
| 8 |
+ var deviceID: String = "" |
|
| 9 |
+ var computedAt: Date = Date.now |
|
| 10 |
+ var checksumBefore: String = "" |
|
| 11 |
+ var checksumAfter: String = "" |
|
| 12 |
+ var isCloudKitImported: Bool = false |
|
| 13 | 13 |
@Relationship(deleteRule: .cascade, inverse: \TypeDelta.delta) |
| 14 |
- var typeDeltas: [TypeDelta]? |
|
| 14 |
+ var typeDeltas: [TypeDelta]? = [] |
|
| 15 | 15 |
|
| 16 | 16 |
init(fromSnapshotID: UUID, toSnapshotID: UUID, deviceID: String) {
|
| 17 | 17 |
self.id = UUID() |
| 18 | 18 |
self.fromSnapshotID = fromSnapshotID |
| 19 | 19 |
self.toSnapshotID = toSnapshotID |
| 20 | 20 |
self.deviceID = deviceID |
| 21 |
- self.computedAt = Date.now |
|
| 22 |
- self.checksumBefore = "" |
|
| 23 |
- self.checksumAfter = "" |
|
| 24 |
- self.isCloudKitImported = false |
|
| 25 |
- self.typeDeltas = [] |
|
| 26 | 21 |
} |
| 27 | 22 |
} |
@@ -1,32 +1,25 @@ |
||
| 1 | 1 |
import Foundation |
| 2 | 2 |
import SwiftData |
| 3 | 3 |
|
| 4 |
-@Model |
|
| 5 |
-final class TypeCount {
|
|
| 6 |
- @Attribute(.unique) var id: UUID |
|
| 7 |
- @Attribute var typeIdentifier: String |
|
| 8 |
- @Attribute var displayName: String |
|
| 9 |
- @Attribute var count: Int |
|
| 10 |
- @Attribute var hash: String |
|
| 11 |
- @Attribute var earliestDate: Date? |
|
| 12 |
- @Attribute var latestDate: Date? |
|
| 13 |
- @Attribute var quality: SnapshotQuality |
|
| 14 |
- @Attribute var isUnsupported: Bool |
|
| 15 |
- @Attribute var snapshot: HealthSnapshot? |
|
| 4 |
+@Model final class TypeCount {
|
|
| 5 |
+ var id: UUID = UUID() |
|
| 6 |
+ var typeIdentifier: String = "" |
|
| 7 |
+ var displayName: String = "" |
|
| 8 |
+ var count: Int = 0 |
|
| 9 |
+ var hash: String = "" |
|
| 10 |
+ var earliestDate: Date? |
|
| 11 |
+ var latestDate: Date? |
|
| 12 |
+ var quality: SnapshotQuality = .complete |
|
| 13 |
+ var isUnsupported: Bool = false |
|
| 14 |
+ var snapshot: HealthSnapshot? |
|
| 16 | 15 |
@Relationship(deleteRule: .cascade, inverse: \YearlyCount.typeCount) |
| 17 |
- var yearlyCounts: [YearlyCount]? |
|
| 16 |
+ var yearlyCounts: [YearlyCount]? = [] |
|
| 18 | 17 |
|
| 19 |
- init(typeIdentifier: String, displayName: String, count: Int, quality: SnapshotQuality = SnapshotQuality.complete) {
|
|
| 18 |
+ init(typeIdentifier: String, displayName: String, count: Int, quality: SnapshotQuality = .complete) {
|
|
| 20 | 19 |
self.id = UUID() |
| 21 | 20 |
self.typeIdentifier = typeIdentifier |
| 22 | 21 |
self.displayName = displayName |
| 23 | 22 |
self.count = count |
| 24 |
- self.hash = "" |
|
| 25 |
- self.earliestDate = nil |
|
| 26 |
- self.latestDate = nil |
|
| 27 | 23 |
self.quality = quality |
| 28 |
- self.isUnsupported = false |
|
| 29 |
- self.snapshot = nil |
|
| 30 |
- self.yearlyCounts = [] |
|
| 31 | 24 |
} |
| 32 | 25 |
} |
@@ -2,34 +2,24 @@ import Foundation |
||
| 2 | 2 |
import SwiftData |
| 3 | 3 |
|
| 4 | 4 |
@Model final class TypeDelta {
|
| 5 |
- @Attribute(.unique) var id: UUID |
|
| 6 |
- @Attribute var typeIdentifier: String |
|
| 7 |
- @Attribute var displayName: String |
|
| 8 |
- @Attribute var countDelta: Int |
|
| 9 |
- @Attribute var hashBefore: String |
|
| 10 |
- @Attribute var hashAfter: String |
|
| 11 |
- @Attribute var qualityBeforeRaw: String? |
|
| 12 |
- @Attribute var qualityAfterRaw: String? |
|
| 13 |
- @Attribute var transitionRaw: String |
|
| 14 |
- @Attribute var reasonRaw: String |
|
| 15 |
- @Attribute var yearlyCountNote: String |
|
| 16 |
- @Attribute var isCloudKitImported: Bool |
|
| 5 |
+ var id: UUID = UUID() |
|
| 6 |
+ var typeIdentifier: String = "" |
|
| 7 |
+ var displayName: String = "" |
|
| 8 |
+ var countDelta: Int = 0 |
|
| 9 |
+ var hashBefore: String = "" |
|
| 10 |
+ var hashAfter: String = "" |
|
| 11 |
+ var qualityBeforeRaw: String? |
|
| 12 |
+ var qualityAfterRaw: String? |
|
| 13 |
+ var transitionRaw: String = TypeTransition.unchanged.rawValue |
|
| 14 |
+ var reasonRaw: String = TypeDeltaReason.normal.rawValue |
|
| 15 |
+ var yearlyCountNote: String = "" |
|
| 16 |
+ var isCloudKitImported: Bool = false |
|
| 17 | 17 |
var delta: SnapshotDelta? |
| 18 | 18 |
|
| 19 | 19 |
init(typeIdentifier: String, displayName: String) {
|
| 20 | 20 |
self.id = UUID() |
| 21 | 21 |
self.typeIdentifier = typeIdentifier |
| 22 | 22 |
self.displayName = displayName |
| 23 |
- self.countDelta = 0 |
|
| 24 |
- self.hashBefore = "" |
|
| 25 |
- self.hashAfter = "" |
|
| 26 |
- self.qualityBeforeRaw = nil |
|
| 27 |
- self.qualityAfterRaw = nil |
|
| 28 |
- self.transitionRaw = TypeTransition.unchanged.rawValue |
|
| 29 |
- self.reasonRaw = TypeDeltaReason.normal.rawValue |
|
| 30 |
- self.yearlyCountNote = "" |
|
| 31 |
- self.isCloudKitImported = false |
|
| 32 |
- self.delta = nil |
|
| 33 | 23 |
} |
| 34 | 24 |
} |
| 35 | 25 |
|
@@ -1,13 +1,12 @@ |
||
| 1 | 1 |
import Foundation |
| 2 | 2 |
import SwiftData |
| 3 | 3 |
|
| 4 |
-@Model |
|
| 5 |
-final class YearlyCount {
|
|
| 6 |
- @Attribute(.unique) var id: UUID |
|
| 7 |
- @Attribute var year: Int |
|
| 8 |
- @Attribute var count: Int |
|
| 9 |
- @Attribute var typeIdentifier: String |
|
| 10 |
- @Attribute var isApproximate: Bool |
|
| 4 |
+@Model final class YearlyCount {
|
|
| 5 |
+ var id: UUID = UUID() |
|
| 6 |
+ var year: Int = 0 |
|
| 7 |
+ var count: Int = 0 |
|
| 8 |
+ var typeIdentifier: String = "" |
|
| 9 |
+ var isApproximate: Bool = false |
|
| 11 | 10 |
var typeCount: TypeCount? |
| 12 | 11 |
|
| 13 | 12 |
init(year: Int, count: Int, typeIdentifier: String, isApproximate: Bool = false) {
|
@@ -16,6 +15,5 @@ final class YearlyCount {
|
||
| 16 | 15 |
self.count = count |
| 17 | 16 |
self.typeIdentifier = typeIdentifier |
| 18 | 17 |
self.isApproximate = isApproximate |
| 19 |
- self.typeCount = nil |
|
| 20 | 18 |
} |
| 21 | 19 |
} |