Skip to content

Commit 2b020c6

Browse files
1.60.35
1 parent bb7f955 commit 2b020c6

4 files changed

+72
-17
lines changed

StrongBox/Strongbox.entitlements

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
<dict>
55
<key>aps-environment</key>
66
<string>Production</string>
7-
<key>com.apple.developer.aps-environment</key>
8-
<string>Production</string>
9-
<key>com.apple.developer.icloud-container-environment</key>
10-
<string>Production</string>
7+
<key>com.apple.developer.aps-environment</key>
8+
<string>Production</string>
9+
<key>com.apple.developer.icloud-container-environment</key>
10+
<string>Production</string>
1111
<key>com.apple.developer.authentication-services.autofill-credential-provider</key>
1212
<true/>
1313
<key>com.apple.developer.default-data-protection</key>

model/cloudkit/CloudKitDatabasesInteractor.swift

+12-11
Original file line numberDiff line numberDiff line change
@@ -330,12 +330,14 @@ class CloudKitDatabasesInteractor: NSObject {
330330
}
331331

332332
func mergeOrUpdateDatabases(_ ckDbs: [CloudKitHostedDatabase]) async throws {
333-
removeNoneExistentDatabases(ckDbs)
333+
removeDeletedDatabases(ckDbs)
334334

335335

336336

337337
for db in ckDbs {
338-
try await mergeCloudKitDatabaseIn(db)
338+
if db.deletedAt == nil {
339+
try await mergeCloudKitDatabaseIn(db)
340+
}
339341
}
340342
}
341343

@@ -412,18 +414,17 @@ class CloudKitDatabasesInteractor: NSObject {
412414
}
413415
}
414416

415-
func removeNoneExistentDatabases(_ ckDbs: [CloudKitHostedDatabase]) {
417+
private func removeDeletedDatabases(_ ckDbs: [CloudKitHostedDatabase]) {
418+
419+
416420

417421

418-
let allIds = Set(ckDbs.map(\.id))
419-
420-
let toRemove = existingCloudKitDatabases.filter { db in
421-
guard let cloudKitDatabaseId = cloudKitIdentifierFromStrongboxDatabase(db) else {
422-
swlog("🔴 ERROR: Could not read fileId! \(#function)!!")
423-
return true
424-
}
422+
let deletedCkDbs = ckDbs.filter { ckDb in
423+
ckDb.deletedAt != nil
424+
}
425425

426-
return !allIds.contains(cloudKitDatabaseId)
426+
let toRemove = deletedCkDbs.compactMap { deletedCkDb in
427+
findStrongboxDatabaseForCloudKitDatabase(cloudKitIdentifier: deletedCkDb.id)
427428
}
428429

429430
for removeMe in toRemove {

model/cloudkit/CloudKitHostedDatabase.swift

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ extension CloudKitHostedDatabase {
1515
static let filename = "filename"
1616
static let dataBlob = "dataBlob"
1717
static let modDate = "modDate"
18+
static let deletedAt = "deletedAt"
1819
}
1920
}
2021

@@ -24,6 +25,7 @@ struct CloudKitHostedDatabase: Identifiable {
2425
let nickname: String
2526
let filename: String
2627
let modDate: Date
28+
let deletedAt: Date?
2729
let dataBlob: Data?
2830
let associatedCkRecord: CKRecord
2931
let sharedWithMe: Bool
@@ -55,9 +57,12 @@ struct CloudKitHostedDatabase: Identifiable {
5557
return nil
5658
}
5759

60+
let deletedAt = record.encryptedValues[RecordKeys.deletedAt] as? Date
61+
5862
self.nickname = nickname
5963
self.filename = filename
6064
self.modDate = modDate
65+
self.deletedAt = deletedAt
6166

6267
if let asset = record[RecordKeys.dataBlob] as? CKAsset {
6368

model/cloudkit/CloudKitManager.swift

+51-2
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class CloudKitManager {
112112
CloudKitHostedDatabase.RecordKeys.nickname,
113113
CloudKitHostedDatabase.RecordKeys.filename,
114114
CloudKitHostedDatabase.RecordKeys.modDate,
115+
CloudKitHostedDatabase.RecordKeys.deletedAt,
115116
CKRecord.SystemFieldKey.share,
116117
]
117118

@@ -148,11 +149,12 @@ class CloudKitManager {
148149
CloudKitHostedDatabase.RecordKeys.nickname,
149150
CloudKitHostedDatabase.RecordKeys.filename,
150151
CloudKitHostedDatabase.RecordKeys.modDate,
152+
CloudKitHostedDatabase.RecordKeys.deletedAt,
151153
CKRecord.SystemFieldKey.share,
152154

153155
]
154156

155-
return try await executeCloudKitOperation(theDatabase: cloudKitDatabase) { database in
157+
let all = try await executeCloudKitOperation(theDatabase: cloudKitDatabase) { database in
156158
var all: [CloudKitHostedDatabase] = []
157159

158160
let (results, initialQueryCursor) = try await database.records(matching: query, inZoneWith: zone.zoneID, desiredKeys: desiredKeys)
@@ -178,6 +180,34 @@ class CloudKitManager {
178180

179181
return all
180182
}
183+
184+
185+
186+
maintenanceDeleteOldDatabasesMarkedDeletedAt(all)
187+
188+
return all
189+
}
190+
191+
func maintenanceDeleteOldDatabasesMarkedDeletedAt(_ databases: [CloudKitHostedDatabase]) {
192+
let olds = databases.filter { ckDb in
193+
if !ckDb.sharedWithMe, let deletedAt = ckDb.deletedAt, (deletedAt as NSDate).isMoreThanXDaysAgo(90) {
194+
return true
195+
} else {
196+
return false
197+
}
198+
}
199+
200+
if !olds.isEmpty {
201+
Task {
202+
for old in olds {
203+
do {
204+
try await deleteActual(id: old.id)
205+
} catch {
206+
swlog("🔴 Cannot cleanup an old database [\(old)] marked deleted more than 90 days ago.")
207+
}
208+
}
209+
}
210+
}
181211
}
182212

183213
func updateDatabase(_ id: CloudKitDatabaseIdentifier, dataBlob: Data) async throws -> CloudKitHostedDatabase {
@@ -195,6 +225,22 @@ class CloudKitManager {
195225
}
196226

197227
func delete(id: CloudKitDatabaseIdentifier) async throws {
228+
229+
230+
231+
232+
233+
234+
235+
let existing = try await getDatabase(id: id, includeDataBlob: false)
236+
237+
238+
239+
240+
_ = try await saveOrUpdate(existing.associatedCkRecord, sharedWithMe: id.sharedWithMe, modDate: .now, dataBlob: Data(), deletedAt: .now)
241+
}
242+
243+
func deleteActual(id: CloudKitDatabaseIdentifier) async throws {
198244
guard !id.sharedWithMe else {
199245
swlog("🔴 Cannot delete a database we don't own")
200246
throw CloudKitManagerError.invalidParameters
@@ -207,13 +253,16 @@ class CloudKitManager {
207253
}
208254
}
209255

210-
private func saveOrUpdate(_ ckRecord: CKRecord, sharedWithMe: Bool, nickName: String? = nil, fileName: String? = nil, modDate: Date? = nil, dataBlob: Data? = nil) async throws -> CloudKitHostedDatabase {
256+
private func saveOrUpdate(_ ckRecord: CKRecord, sharedWithMe: Bool, nickName: String? = nil, fileName: String? = nil, modDate: Date? = nil, dataBlob: Data? = nil, deletedAt: Date? = nil) async throws -> CloudKitHostedDatabase {
211257
if let nickName {
212258
ckRecord.encryptedValues[CloudKitHostedDatabase.RecordKeys.nickname] = nickName
213259
}
214260
if let fileName {
215261
ckRecord.encryptedValues[CloudKitHostedDatabase.RecordKeys.filename] = fileName
216262
}
263+
if let deletedAt {
264+
ckRecord.encryptedValues[CloudKitHostedDatabase.RecordKeys.deletedAt] = deletedAt
265+
}
217266

218267
var tmpAssetUrlToDelete: URL? = nil
219268

0 commit comments

Comments
 (0)