Skip to content

Commit 59d4586

Browse files
committed
Add iCloud syncing
1 parent 198e4fc commit 59d4586

5 files changed

Lines changed: 55 additions & 22 deletions

File tree

InfiniLink/Core/DeviceView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ struct DeviceView: View {
106106
Image("logo.bluetooth")
107107
.resizable()
108108
.frame(width: 21, height: 35)
109+
.foregroundStyle(.blue)
109110
VStack(alignment: .leading, spacing: 3) {
110111
Text("Bluetooth Disabled")
111112
.foregroundStyle(Color.primary)

InfiniLink/InfiniLink.entitlements

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,20 @@
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<plist version="1.0">
44
<dict>
5+
<key>aps-environment</key>
6+
<string>development</string>
57
<key>com.apple.developer.healthkit</key>
68
<true/>
79
<key>com.apple.developer.healthkit.background-delivery</key>
810
<true/>
11+
<key>com.apple.developer.icloud-container-identifiers</key>
12+
<array>
13+
<string>iCloud.com.alexemry.Infini-iOS</string>
14+
</array>
15+
<key>com.apple.developer.icloud-services</key>
16+
<array>
17+
<string>CloudKit</string>
18+
</array>
919
<key>com.apple.developer.weatherkit</key>
1020
<true/>
1121
<key>com.apple.security.app-sandbox</key>
Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="23605" systemVersion="24D70" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithSwiftData="YES" userDefinedModelVersionIdentifier="">
2+
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="23788" systemVersion="24D70" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="YES" usedWithSwiftData="YES" userDefinedModelVersionIdentifier="">
33
<entity name="BatteryDataPoint" representedClassName="BatteryDataPoint" syncable="YES" codeGenerationType="class">
44
<attribute name="deviceId" optional="YES" attributeType="String"/>
55
<attribute name="id" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
@@ -8,24 +8,24 @@
88
</entity>
99
<entity name="Device" representedClassName="Device" syncable="YES" codeGenerationType="class">
1010
<attribute name="alwaysOnDisplay" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
11-
<attribute name="blefsVersion" attributeType="String"/>
12-
<attribute name="bleUUID" attributeType="String"/>
11+
<attribute name="blefsVersion" attributeType="String" defaultValueString=""/>
12+
<attribute name="bleUUID" attributeType="String" defaultValueString=""/>
1313
<attribute name="brightLevel" attributeType="Integer 16" defaultValueString="1" usesScalarValueType="YES"/>
1414
<attribute name="chimesOption" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
1515
<attribute name="clockType" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
16-
<attribute name="firmware" attributeType="String"/>
17-
<attribute name="hardwareRevision" attributeType="String"/>
18-
<attribute name="manufacturer" attributeType="String"/>
19-
<attribute name="modelNumber" attributeType="String"/>
16+
<attribute name="firmware" attributeType="String" defaultValueString=""/>
17+
<attribute name="hardwareRevision" attributeType="String" defaultValueString=""/>
18+
<attribute name="manufacturer" attributeType="String" defaultValueString=""/>
19+
<attribute name="modelNumber" attributeType="String" defaultValueString=""/>
2020
<attribute name="name" optional="YES" attributeType="String"/>
2121
<attribute name="notificationStatus" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
2222
<attribute name="screenTimeout" attributeType="Integer 32" defaultValueString="15000" usesScalarValueType="YES"/>
23-
<attribute name="serial" attributeType="String"/>
23+
<attribute name="serial" attributeType="String" defaultValueString=""/>
2424
<attribute name="settingsVersion" attributeType="Integer 32" defaultValueString="4" usesScalarValueType="YES"/>
2525
<attribute name="shakeWakeThreshold" attributeType="Integer 16" defaultValueString="150" usesScalarValueType="YES"/>
26-
<attribute name="softwareRevision" attributeType="String"/>
26+
<attribute name="softwareRevision" attributeType="String" defaultValueString=""/>
2727
<attribute name="stepsGoal" attributeType="Integer 32" defaultValueString="10000" usesScalarValueType="YES"/>
28-
<attribute name="uuid" attributeType="String"/>
28+
<attribute name="uuid" attributeType="String" defaultValueString=""/>
2929
<attribute name="watchface" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
3030
<attribute name="weatherFormat" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
3131
<relationship name="pineTimeStyle" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PineTimeStyleWatchface" inverseName="device" inverseEntity="PineTimeStyleWatchface"/>
@@ -34,7 +34,7 @@
3434
<entity name="HeartDataPoint" representedClassName="HeartDataPoint" syncable="YES" codeGenerationType="class">
3535
<attribute name="deviceId" optional="YES" attributeType="String"/>
3636
<attribute name="id" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
37-
<attribute name="timestamp" attributeType="Date" usesScalarValueType="NO"/>
37+
<attribute name="timestamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
3838
<attribute name="value" attributeType="Double" defaultValueString="0" usesScalarValueType="YES"/>
3939
<relationship name="exercise" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="UserExercise" inverseName="heartPoints" inverseEntity="UserExercise"/>
4040
</entity>
@@ -53,9 +53,9 @@
5353
</entity>
5454
<entity name="SleepDataPoint" representedClassName="SleepDataPoint" syncable="YES" codeGenerationType="class">
5555
<attribute name="deviceId" optional="YES" attributeType="String"/>
56-
<attribute name="id" attributeType="UUID" usesScalarValueType="NO"/>
56+
<attribute name="id" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
5757
<attribute name="minutes" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
58-
<attribute name="timestamp" attributeType="Date" usesScalarValueType="NO"/>
58+
<attribute name="timestamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
5959
</entity>
6060
<entity name="StepCounts" representedClassName="StepCounts" syncable="YES" codeGenerationType="class">
6161
<attribute name="deviceId" optional="YES" attributeType="String"/>
@@ -66,11 +66,11 @@
6666
<entity name="UserExercise" representedClassName="UserExercise" syncable="YES" codeGenerationType="class">
6767
<attribute name="caloriesBurned" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
6868
<attribute name="deviceId" optional="YES" attributeType="String"/>
69-
<attribute name="endDate" attributeType="Date" usesScalarValueType="NO"/>
70-
<attribute name="exerciseId" attributeType="String"/>
69+
<attribute name="endDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
70+
<attribute name="exerciseId" optional="YES" attributeType="String"/>
7171
<attribute name="id" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
72-
<attribute name="startDate" attributeType="Date" usesScalarValueType="NO"/>
72+
<attribute name="startDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
7373
<attribute name="steps" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
7474
<relationship name="heartPoints" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="HeartDataPoint" inverseName="exercise" inverseEntity="HeartDataPoint"/>
7575
</entity>
76-
</model>
76+
</model>

InfiniLink/Info.plist

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
<string>bluetooth-central</string>
7676
<string>fetch</string>
7777
<string>processing</string>
78+
<string>remote-notification</string>
7879
</array>
7980
<key>UILaunchScreen</key>
8081
<dict/>
@@ -91,5 +92,17 @@
9192
</array>
9293
<key>kTCCServiceMediaLibrary</key>
9394
<string>This app needs permission to allow your PineTime to control your music.</string>
95+
<key>com.apple.developer.icloud-container-identifiers</key>
96+
<array>
97+
<string>iCloud.com.alexemry.Infini-iOS</string>
98+
</array>
99+
<key>com.apple.developer.icloud-services</key>
100+
<array>
101+
<string>CloudKit</string>
102+
</array>
103+
<key>com.apple.developer.ubiquity-container-identifiers</key>
104+
<array>
105+
<string>iCloud.com.alexemry.Infini-iOS</string>
106+
</array>
94107
</dict>
95108
</plist>

InfiniLink/Utils/PersistenceController.swift

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,31 @@
66
//
77

88
import CoreData
9+
import CloudKit
910

1011
struct PersistenceController {
1112
static let shared = PersistenceController()
1213

13-
let container: NSPersistentContainer
14+
let container: NSPersistentCloudKitContainer
1415

1516
init() {
16-
container = NSPersistentContainer(name: "InfiniLink")
17+
container = NSPersistentCloudKitContainer(name: "InfiniLink")
18+
19+
guard let description = container.persistentStoreDescriptions.first else {
20+
log("No persistent store descriptions")
21+
return
22+
}
23+
24+
description.shouldMigrateStoreAutomatically = true
25+
description.shouldInferMappingModelAutomatically = true
26+
description.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.com.alexemry.Infini-iOS")
27+
1728
container.loadPersistentStores { storeDescription, error in
18-
storeDescription.shouldMigrateStoreAutomatically = true
19-
storeDescription.shouldInferMappingModelAutomatically = true
20-
2129
if let error = error as NSError? {
2230
fatalError("Unresolved error \(error), \(error.userInfo)")
2331
}
2432
}
33+
2534
container.viewContext.automaticallyMergesChangesFromParent = true
2635
}
2736
}

0 commit comments

Comments
 (0)