perf: reduce redundant device queries

This commit is contained in:
CelloSerenity 2026-09-27 13:26:07 -06:00
parent cbaf467b66
commit f50353c643
2 changed files with 24 additions and 22 deletions

View file

@ -21,6 +21,8 @@ final class InstalledAppsViewModel: ObservableObject {
private let cacheKeyNonDebuggable = "cachedNonDebuggableApps" private let cacheKeyNonDebuggable = "cachedNonDebuggableApps"
private let cacheKeySystem = "cachedSystemApps" private let cacheKeySystem = "cachedSystemApps"
private var cancellables: Set<AnyCancellable> = [] private var cancellables: Set<AnyCancellable> = []
private var refreshInProgress = false
private var refreshPending = false
init() { init() {
loadCachedApps() loadCachedApps()
@ -32,6 +34,12 @@ final class InstalledAppsViewModel: ObservableObject {
} }
func refreshAppLists() { func refreshAppLists() {
guard !refreshInProgress else {
refreshPending = true
return
}
refreshInProgress = true
isLoading = true isLoading = true
lastError = nil lastError = nil
@ -47,6 +55,11 @@ final class InstalledAppsViewModel: ObservableObject {
debuggable: debuggable, debuggable: debuggable,
hiddenSystem: hiddenSystem hiddenSystem: hiddenSystem
) )
self.cacheApps(
debuggable: debuggable,
nonDebuggable: classifiedApps.nonDebuggable,
system: classifiedApps.system
)
DispatchQueue.main.async { DispatchQueue.main.async {
self.apply( self.apply(
@ -54,22 +67,26 @@ final class InstalledAppsViewModel: ObservableObject {
nonDebuggable: classifiedApps.nonDebuggable, nonDebuggable: classifiedApps.nonDebuggable,
system: classifiedApps.system system: classifiedApps.system
) )
self.isLoading = false self.finishRefresh()
self.cacheApps(
debuggable: debuggable,
nonDebuggable: classifiedApps.nonDebuggable,
system: classifiedApps.system
)
} }
} catch { } catch {
DispatchQueue.main.async { DispatchQueue.main.async {
self.isLoading = false
self.lastError = error.localizedDescription self.lastError = error.localizedDescription
self.finishRefresh()
} }
} }
} }
} }
private func finishRefresh() {
refreshInProgress = false
isLoading = false
guard refreshPending else { return }
refreshPending = false
refreshAppLists()
}
func displayName(for bundleID: String) -> String? { func displayName(for bundleID: String) -> String? {
debuggableApps[bundleID] ?? systemApps[bundleID] ?? nonDebuggableApps[bundleID] debuggableApps[bundleID] ?? systemApps[bundleID] ?? nonDebuggableApps[bundleID]
} }

View file

@ -12,8 +12,6 @@ struct HomeView: View {
@AppStorage("bundleID") private var bundleID: String = "" @AppStorage("bundleID") private var bundleID: String = ""
@AppStorage(UserDefaults.Keys.confirmExternalJITRequests) private var confirmExternalJITRequests = true @AppStorage(UserDefaults.Keys.confirmExternalJITRequests) private var confirmExternalJITRequests = true
@ObservedObject private var mounting = MountingProgress.shared
@State private var hasAppeared = false @State private var hasAppeared = false
@State private var pendingJITEnableConfiguration: JITEnableConfiguration? @State private var pendingJITEnableConfiguration: JITEnableConfiguration?
@State private var isShowingPairingFilePicker = false @State private var isShowingPairingFilePicker = false
@ -22,8 +20,6 @@ struct HomeView: View {
@State private var pendingLiveContainerApp: LiveContainerApp? @State private var pendingLiveContainerApp: LiveContainerApp?
@State private var scriptRunModel: RunJSViewModel? @State private var scriptRunModel: RunJSViewModel?
private let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
private struct DebugFeedback: Identifiable { private struct DebugFeedback: Identifiable {
let id = UUID() let id = UUID()
let message: String let message: String
@ -53,9 +49,6 @@ struct HomeView: View {
} }
.onAppear(perform: handleAppear) .onAppear(perform: handleAppear)
.onReceive(NotificationCenter.default.publisher(for: .intentJSScriptReady), perform: handleScriptReadyNotification) .onReceive(NotificationCenter.default.publisher(for: .intentJSScriptReady), perform: handleScriptReadyNotification)
.onReceive(timer) { _ in
refreshMountStatusIfNeeded()
}
.onOpenURL { url in .onOpenURL { url in
handleExternalURL(url) handleExternalURL(url)
} }
@ -130,7 +123,6 @@ struct HomeView: View {
private func handleAppear() { private func handleAppear() {
startTunnelInBackground() startTunnelInBackground()
MountingProgress.shared.checkforMounted()
hasAppeared = true hasAppeared = true
if let config = pendingJITEnableConfiguration { if let config = pendingJITEnableConfiguration {
@ -153,13 +145,6 @@ struct HomeView: View {
scriptRunModel = model scriptRunModel = model
} }
private func refreshMountStatusIfNeeded() {
guard mounting.mountingThread == nil, !mounting.coolisMounted else {
return
}
MountingProgress.shared.checkforMounted()
}
private func importPairingFile(_ result: Result<URL, Error>) { private func importPairingFile(_ result: Result<URL, Error>) {
switch result { switch result {
case .success(let url): case .success(let url):