mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Add a search backfill app background processing task
To run when the device is idle, charging and connected to the network.
This commit is contained in:
@@ -170,6 +170,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
observeAppLockChanges()
|
observeAppLockChanges()
|
||||||
|
|
||||||
registerBackgroundAppRefresh()
|
registerBackgroundAppRefresh()
|
||||||
|
registerSearchBackfill()
|
||||||
|
|
||||||
appSettings.analyticsConsentStatePublisher
|
appSettings.analyticsConsentStatePublisher
|
||||||
.dropFirst() // Sentry is configured during init; only reconfigure when consent state actually changes
|
.dropFirst() // Sentry is configured during init; only reconfigure when consent state actually changes
|
||||||
@@ -1189,6 +1190,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
|
|
||||||
scheduleDelayedPauseServices()
|
scheduleDelayedPauseServices()
|
||||||
scheduleBackgroundAppRefresh()
|
scheduleBackgroundAppRefresh()
|
||||||
|
scheduleSearchBackfill()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -1325,3 +1327,63 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Search backfill
|
||||||
|
|
||||||
|
private extension AppCoordinator {
|
||||||
|
func registerSearchBackfill() {
|
||||||
|
let result = BGTaskScheduler.shared.register(forTaskWithIdentifier: appSettings.searchBackfillTaskIdentifier, using: .main) { [weak self] task in
|
||||||
|
guard let task = task as? BGProcessingTask else {
|
||||||
|
MXLog.error("Invalid search backfill configuration")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Task {
|
||||||
|
await self?.handleSearchBackfill(task)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MXLog.info("Register search backfill with result: \(result)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func scheduleSearchBackfill() {
|
||||||
|
guard let userSession, userSession.userSettings.globalSearchEnabled, #available(iOS 26.0, *) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let request = BGProcessingTaskRequest(identifier: appSettings.searchBackfillTaskIdentifier)
|
||||||
|
request.requiresExternalPower = true
|
||||||
|
request.requiresNetworkConnectivity = true
|
||||||
|
|
||||||
|
do {
|
||||||
|
try BGTaskScheduler.shared.submit(request)
|
||||||
|
MXLog.info("Successfully scheduled search backfill task")
|
||||||
|
} catch {
|
||||||
|
MXLog.error("Failed scheduling search backfill with error: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSearchBackfill(_ task: BGProcessingTask) async {
|
||||||
|
MXLog.info("Started search backfill task")
|
||||||
|
|
||||||
|
guard let clientProxy = userSession?.clientProxy else {
|
||||||
|
task.setTaskCompleted(success: false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
task.expirationHandler = { @Sendable [weak self] in
|
||||||
|
MXLog.info("Search backfill task is about to expire.")
|
||||||
|
Task { @MainActor in self?.userSession?.clientProxy.stopSearchBackfill() }
|
||||||
|
}
|
||||||
|
|
||||||
|
clientProxy.startSearchBackfill(strategy: .background)
|
||||||
|
|
||||||
|
// TaskHandle can't be awaited, so poll until the sweep finishes or is stopped on expiry.
|
||||||
|
while clientProxy.isSearchBackfillRunning {
|
||||||
|
try? await Task.sleep(for: .seconds(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
MXLog.info("Marking search backfill task as complete.")
|
||||||
|
task.setTaskCompleted(success: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -151,6 +151,8 @@ final nonisolated class AppSettings: @unchecked Sendable {
|
|||||||
|
|
||||||
/// The task identifier used for background app refresh. Also used in main target's the Info.plist
|
/// The task identifier used for background app refresh. Also used in main target's the Info.plist
|
||||||
let backgroundAppRefreshTaskIdentifier = "io.element.elementx.background.refresh"
|
let backgroundAppRefreshTaskIdentifier = "io.element.elementx.background.refresh"
|
||||||
|
/// The task identifier used for the search index backfill. Also used in main target's the Info.plist
|
||||||
|
let searchBackfillTaskIdentifier = "io.element.elementx.background.search-backfill"
|
||||||
|
|
||||||
/// A URL where users can go read more about the app.
|
/// A URL where users can go read more about the app.
|
||||||
private(set) var websiteURL: URL = "https://element.io"
|
private(set) var websiteURL: URL = "https://element.io"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<key>BGTaskSchedulerPermittedIdentifiers</key>
|
<key>BGTaskSchedulerPermittedIdentifiers</key>
|
||||||
<array>
|
<array>
|
||||||
<string>io.element.elementx.background.refresh</string>
|
<string>io.element.elementx.background.refresh</string>
|
||||||
|
<string>io.element.elementx.background.search-backfill</string>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
|
|||||||
@@ -100,7 +100,8 @@ targets:
|
|||||||
location
|
location
|
||||||
]
|
]
|
||||||
BGTaskSchedulerPermittedIdentifiers: [
|
BGTaskSchedulerPermittedIdentifiers: [
|
||||||
io.element.elementx.background.refresh
|
io.element.elementx.background.refresh,
|
||||||
|
io.element.elementx.background.search-backfill
|
||||||
]
|
]
|
||||||
UTExportedTypeDeclarations:
|
UTExportedTypeDeclarations:
|
||||||
- UTTypeConformsTo: [public.text]
|
- UTTypeConformsTo: [public.text]
|
||||||
|
|||||||
Reference in New Issue
Block a user