Fix issues around upgrading (#173)

* Re-check after

* Completion

* Relaunch
This commit is contained in:
Max Goedjen 2020-11-12 22:55:52 -08:00 committed by GitHub
parent 08b5c7b13c
commit 76514d410b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 17 deletions

View File

@ -28,19 +28,16 @@ struct Secretive: App {
.onAppear { .onAppear {
if !hasRunSetup { if !hasRunSetup {
showingSetup = true showingSetup = true
} else {
if agentStatusChecker.running && justUpdatedChecker.justUpdated {
// Relaunch the agent, since it'll be running from earlier update still
_ = LaunchAgentController().install()
}
} }
} }
.onReceive(NotificationCenter.default.publisher(for: NSApplication.willBecomeActiveNotification)) { _ in .onReceive(NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification)) { _ in
guard hasRunSetup else { return }
agentStatusChecker.check() agentStatusChecker.check()
if hasRunSetup && !agentStatusChecker.running { if agentStatusChecker.running && justUpdatedChecker.justUpdated {
// We've run setup, we didn't just update, launchd is just not doing it's thing. // Relaunch the agent, since it'll be running from earlier update still
// Force a launch directly. reinstallAgent()
LaunchAgentController().forceLaunch() } else if !agentStatusChecker.running {
forceLaunchAgent()
} }
} }
} }
@ -67,6 +64,31 @@ struct Secretive: App {
} }
extension Secretive {
private func reinstallAgent() {
justUpdatedChecker.check()
LaunchAgentController().install {
// Wait a second for launchd to kick in (next runloop isn't enough).
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
agentStatusChecker.check()
if !agentStatusChecker.running {
forceLaunchAgent()
}
}
}
}
private func forceLaunchAgent() {
// We've run setup, we didn't just update, launchd is just not doing it's thing.
// Force a launch directly.
LaunchAgentController().forceLaunch { _ in
agentStatusChecker.check()
}
}
}
private enum Constants { private enum Constants {
static let helpURL = URL(string: "https://github.com/maxgoedjen/secretive/blob/main/FAQ.md")! static let helpURL = URL(string: "https://github.com/maxgoedjen/secretive/blob/main/FAQ.md")!

View File

@ -18,9 +18,7 @@ class JustUpdatedChecker: ObservableObject, JustUpdatedCheckerProtocol {
let lastBuild = UserDefaults.standard.object(forKey: Constants.previousVersionUserDefaultsKey) as? String ?? "None" let lastBuild = UserDefaults.standard.object(forKey: Constants.previousVersionUserDefaultsKey) as? String ?? "None"
let currentBuild = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String let currentBuild = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
UserDefaults.standard.set(currentBuild, forKey: Constants.previousVersionUserDefaultsKey) UserDefaults.standard.set(currentBuild, forKey: Constants.previousVersionUserDefaultsKey)
if lastBuild != currentBuild { justUpdated = lastBuild != currentBuild
justUpdated = true
}
} }

View File

@ -5,16 +5,24 @@ import OSLog
struct LaunchAgentController { struct LaunchAgentController {
func install() -> Bool { func install(completion: (() -> Void)? = nil) {
Logger().debug("Installing agent") Logger().debug("Installing agent")
_ = setEnabled(false) _ = setEnabled(false)
return setEnabled(true) // This is definitely a bit of a "seems to work better" thing but:
// Seems to more reliably hit if these are on separate runloops, otherwise it seems like it sometimes doesn't kill old
// and start new?
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
_ = setEnabled(true)
completion?()
}
} }
func forceLaunch() { func forceLaunch(completion: ((Bool) -> Void)?) {
Logger().debug("Agent is not running, attempting to force launch") Logger().debug("Agent is not running, attempting to force launch")
let url = Bundle.main.bundleURL.appendingPathComponent("Contents/Library/LoginItems/SecretAgent.app") let url = Bundle.main.bundleURL.appendingPathComponent("Contents/Library/LoginItems/SecretAgent.app")
NSWorkspace.shared.openApplication(at: url, configuration: NSWorkspace.OpenConfiguration()) { app, error in NSWorkspace.shared.openApplication(at: url, configuration: NSWorkspace.OpenConfiguration()) { app, error in
completion?(error == nil)
if let error = error { if let error = error {
Logger().error("Error force launching \(error.localizedDescription)") Logger().error("Error force launching \(error.localizedDescription)")
} else { } else {

View File

@ -157,7 +157,7 @@ struct SecretAgentSetupView: View {
} }
func install() { func install() {
_ = LaunchAgentController().install() LaunchAgentController().install()
buttonAction() buttonAction()
} }