Skip to content

Commit 6b92e8f

Browse files
committed
Add weekly background Kyoto CBF sync task (#352)
1 parent 40d7337 commit 6b92e8f

File tree

3 files changed

+87
-1
lines changed

3 files changed

+87
-1
lines changed

BDKSwiftExampleWallet/App/BDKSwiftExampleWalletApp.swift

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,20 @@
66
//
77

88
import BitcoinDevKit
9+
import BackgroundTasks
910
import SwiftUI
1011

1112
@main
1213
struct BDKSwiftExampleWalletApp: App {
1314
@AppStorage("isOnboarding") var isOnboarding: Bool = true
1415
@State private var navigationPath = NavigationPath()
1516
@State private var refreshTrigger = UUID()
17+
@Environment(\.scenePhase) private var scenePhase
18+
19+
init() {
20+
BackgroundCBFSyncTask.register()
21+
BackgroundCBFSyncTask.schedule()
22+
}
1623

1724
var body: some Scene {
1825
WindowGroup {
@@ -30,6 +37,11 @@ struct BDKSwiftExampleWalletApp: App {
3037
BDKClient.live.setNeedsFullScan(true)
3138
navigationPath = NavigationPath()
3239
}
40+
.onChange(of: scenePhase) { _, newValue in
41+
if newValue == .background {
42+
BackgroundCBFSyncTask.schedule()
43+
}
44+
}
3345
}
3446
}
3547
}
@@ -42,3 +54,69 @@ extension BDKSwiftExampleWalletApp {
4254
return (try? KeyClient.live.getBackupInfo()) != nil
4355
}
4456
}
57+
58+
private enum BackgroundCBFSyncTask {
59+
static let identifier = "com.bitcoindevkit.bdkswiftexamplewallet.cbf-sync"
60+
private static let minimumInterval: TimeInterval = 60 * 60 * 24 * 7
61+
62+
static func register() {
63+
BGTaskScheduler.shared.register(
64+
forTaskWithIdentifier: identifier,
65+
using: nil
66+
) { task in
67+
guard let processingTask = task as? BGProcessingTask else {
68+
task.setTaskCompleted(success: false)
69+
return
70+
}
71+
handle(processingTask)
72+
}
73+
}
74+
75+
static func schedule() {
76+
let request = BGProcessingTaskRequest(identifier: identifier)
77+
request.requiresNetworkConnectivity = true
78+
request.requiresExternalPower = true
79+
request.earliestBeginDate = Date(timeIntervalSinceNow: minimumInterval)
80+
81+
do {
82+
try BGTaskScheduler.shared.submit(request)
83+
} catch {
84+
print("[BackgroundCBF] Failed to schedule task: \(error)")
85+
}
86+
}
87+
88+
private static func handle(_ task: BGProcessingTask) {
89+
schedule()
90+
91+
let syncTask = Task.detached(priority: .background) {
92+
do {
93+
try await runKyotoSync()
94+
task.setTaskCompleted(success: true)
95+
} catch {
96+
print("[BackgroundCBF] Background sync failed: \(error)")
97+
task.setTaskCompleted(success: false)
98+
}
99+
}
100+
101+
task.expirationHandler = {
102+
syncTask.cancel()
103+
}
104+
}
105+
106+
private static func runKyotoSync() async throws {
107+
let bdkClient = BDKClient.live
108+
109+
guard (try? bdkClient.getBackupInfo()) != nil else {
110+
return
111+
}
112+
113+
try bdkClient.loadWallet()
114+
115+
guard bdkClient.getClientType() == .kyoto else {
116+
return
117+
}
118+
119+
let inspector = WalletSyncScriptInspector(updateProgress: { _, _ in })
120+
try await bdkClient.syncWithInspector(inspector)
121+
}
122+
}

BDKSwiftExampleWallet/Info.plist

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@
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>BGTaskSchedulerPermittedIdentifiers</key>
6+
<array>
7+
<string>com.bitcoindevkit.bdkswiftexamplewallet.cbf-sync</string>
8+
</array>
59
<key>ITSAppUsesNonExemptEncryption</key>
610
<false/>
711
<key>NSPasteboardUsageDescription</key>
812
<string>"To allow users to copy and paste text between the app and other apps"</string>
13+
<key>UIBackgroundModes</key>
14+
<array>
15+
<string>processing</string>
16+
</array>
917
</dict>
1018
</plist>

BDKSwiftExampleWallet/Service/Key Service/KeyService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ private struct KeyService {
1616
let keychain = Keychain(service: "com.matthewramsden.bdkswiftexamplewallet.testservice")
1717
.label(Bundle.main.displayName)
1818
.synchronizable(false)
19-
.accessibility(.whenUnlocked)
19+
.accessibility(.afterFirstUnlock)
2020
self.keychain = keychain
2121
}
2222

0 commit comments

Comments
 (0)