Skip to content

Commit 03ac820

Browse files
authored
Merge pull request #619 from synonymdev/fix/backup-wallet-id-migration
fix: migrate legacy backups missing wallet id on restore
2 parents 9a3b00e + f71ccd1 commit 03ac820

3 files changed

Lines changed: 34 additions & 5 deletions

File tree

Bitkit.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,7 @@
12011201
repositoryURL = "https://github.com/synonymdev/bitkit-core";
12021202
requirement = {
12031203
kind = exactVersion;
1204-
version = 0.3.9;
1204+
version = 0.4.0;
12051205
};
12061206
};
12071207
96E20CD22CB6D91A00C24149 /* XCRemoteSwiftPackageReference "CodeScanner" */ = {

Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Bitkit/Services/BackupService.swift

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,11 @@ class BackupService {
214214
}
215215

216216
try await performRestore(category: .activity) { dataBytes in
217-
let payload = try JSONDecoder().decode(ActivityBackupV1.self, from: dataBytes)
217+
let migrated = try self.migrateCoreOwnedBackupFields(dataBytes, fieldMigrations: [
218+
"activities": migrateBackupActivitiesJson,
219+
"activityTags": migrateBackupActivityTagsJson,
220+
])
221+
let payload = try JSONDecoder().decode(ActivityBackupV1.self, from: migrated)
218222

219223
try await CoreService.shared.activity.upsertList(payload.activities)
220224
try await CoreService.shared.activity.upsertTags(payload.activityTags)
@@ -227,7 +231,10 @@ class BackupService {
227231
}
228232

229233
try await performRestore(category: .metadata) { dataBytes in
230-
let payload = try JSONDecoder().decode(MetadataBackupV1.self, from: dataBytes)
234+
let migrated = try self.migrateCoreOwnedBackupFields(dataBytes, fieldMigrations: [
235+
"tagMetadata": migrateBackupPreActivityMetadataJson,
236+
])
237+
let payload = try JSONDecoder().decode(MetadataBackupV1.self, from: migrated)
231238

232239
try await CoreService.shared.activity.upsertPreActivityMetadata(payload.tagMetadata)
233240

@@ -762,6 +769,28 @@ class BackupService {
762769
}
763770
}
764771

772+
/// Fills in wallet ids that predate wallet-scoped activity data before a
773+
/// backup envelope is decoded. Each Core-owned array field is handed to the
774+
/// matching Core migration helper as raw JSON, so the app never edits Core
775+
/// model JSON itself. Records that already carry a wallet id are left
776+
/// unchanged, so this is safe to run on current backups too.
777+
private func migrateCoreOwnedBackupFields(
778+
_ dataBytes: Data,
779+
fieldMigrations: [String: (String) throws -> String]
780+
) throws -> Data {
781+
guard var root = try JSONSerialization.jsonObject(with: dataBytes) as? [String: Any] else {
782+
return dataBytes
783+
}
784+
for (field, migrate) in fieldMigrations {
785+
guard let array = root[field] as? [Any] else { continue }
786+
let arrayData = try JSONSerialization.data(withJSONObject: array)
787+
let migratedJson = try migrate(String(decoding: arrayData, as: UTF8.self))
788+
guard let migratedData = migratedJson.data(using: .utf8) else { continue }
789+
root[field] = try JSONSerialization.jsonObject(with: migratedData)
790+
}
791+
return try JSONSerialization.data(withJSONObject: root)
792+
}
793+
765794
private func performRestore(category: BackupCategory, restoreAction: (Data) async throws -> Void) async throws {
766795
do {
767796
let item = try await vssBackupClient.getObject(key: category.rawValue)

0 commit comments

Comments
 (0)