From 5d30f34604648cf67850df60a1ac025ff983f28c Mon Sep 17 00:00:00 2001 From: Lava <34743145+CanglongCl@users.noreply.github.com> Date: Fri, 26 Jan 2024 17:50:34 -0800 Subject: [PATCH] [Refactor] Introduce `GlobalContext` and migrate the updater controller into it (#365) * introduce global context and migrate updater controller into * refactor: mutually initialize global context * revert `@Default` in `EasydictApp` * fix: remove updaterController from Main.storyboard * style: fix typo * fix: updaterDelegate was nil * perf: set updaterHelper to private * perf: remove sparkle code from AppDelegate * perf: remove unused #import header --------- Co-authored-by: Tisfeng --- Easydict.xcodeproj/project.pbxproj | 4 ++ Easydict/App/AppDelegate.h | 3 -- Easydict/App/AppDelegate.m | 25 +---------- Easydict/App/Base.lproj/Main.storyboard | 14 +----- .../Feature/Configuration/Configuration.swift | 10 +---- .../Feature/Configuration/EZConfiguration.h | 3 ++ .../Feature/Configuration/EZConfiguration.m | 10 ++--- .../Feature/StatusItem/EZMenuItemManager.m | 7 +++ Easydict/NewApp/EasydictApp.swift | 39 +++-------------- Easydict/NewApp/Utility/GlobalContext.swift | 43 +++++++++++++++++++ Easydict/NewApp/View/MenuItemView.swift | 20 ++++----- 11 files changed, 83 insertions(+), 95 deletions(-) create mode 100644 Easydict/NewApp/Utility/GlobalContext.swift diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 0feacd3fa..dd2932c73 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -277,6 +277,7 @@ EA9943EE2B5353AB00EE7B97 /* WindowTypeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943ED2B5353AB00EE7B97 /* WindowTypeExtensions.swift */; }; EA9943F02B5354C400EE7B97 /* ShowWindowPositionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943EF2B5354C400EE7B97 /* ShowWindowPositionExtensions.swift */; }; EA9943F22B5358BF00EE7B97 /* LanguageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943F12B5358BF00EE7B97 /* LanguageExtensions.swift */; }; + EAE3D3502B62E9DE001EE3E3 /* GlobalContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAE3D34F2B62E9DE001EE3E3 /* GlobalContext.swift */; }; EAED41EC2B54AA920005FE0A /* ServiceConfigurationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAED41EB2B54AA920005FE0A /* ServiceConfigurationSection.swift */; }; EAED41EF2B54B1430005FE0A /* ConfigurableService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAED41EE2B54B1430005FE0A /* ConfigurableService.swift */; }; EAED41F22B54B39D0005FE0A /* OpenAIService+ConfigurableService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAED41F12B54B39D0005FE0A /* OpenAIService+ConfigurableService.swift */; }; @@ -772,6 +773,7 @@ EA9943ED2B5353AB00EE7B97 /* WindowTypeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowTypeExtensions.swift; sourceTree = ""; }; EA9943EF2B5354C400EE7B97 /* ShowWindowPositionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowWindowPositionExtensions.swift; sourceTree = ""; }; EA9943F12B5358BF00EE7B97 /* LanguageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageExtensions.swift; sourceTree = ""; }; + EAE3D34F2B62E9DE001EE3E3 /* GlobalContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalContext.swift; sourceTree = ""; }; EAED41EB2B54AA920005FE0A /* ServiceConfigurationSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceConfigurationSection.swift; sourceTree = ""; }; EAED41EE2B54B1430005FE0A /* ConfigurableService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurableService.swift; sourceTree = ""; }; EAED41F12B54B39D0005FE0A /* OpenAIService+ConfigurableService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OpenAIService+ConfigurableService.swift"; sourceTree = ""; }; @@ -2230,6 +2232,7 @@ EA9943DD2B534BAE00EE7B97 /* Utility */ = { isa = PBXGroup; children = ( + EAE3D34F2B62E9DE001EE3E3 /* GlobalContext.swift */, EAED41ED2B54B1390005FE0A /* Protocol */, EA9943E62B534D7C00EE7B97 /* Extensions */, ); @@ -2795,6 +2798,7 @@ 0320C5872B29F35700861B3D /* QueryServiceRecord.swift in Sources */, 03FC699A2B39D13A0035D2DA /* EZOpenAIChatResponse.m in Sources */, 03B022FA29231FA6001C7E63 /* EZServiceTypes.m in Sources */, + EAE3D3502B62E9DE001EE3E3 /* GlobalContext.swift in Sources */, EA9943F02B5354C400EE7B97 /* ShowWindowPositionExtensions.swift in Sources */, 03B0233129231FA6001C7E63 /* MMCrash.m in Sources */, 03B0232629231FA6001C7E63 /* NSAttributedString+MM.m in Sources */, diff --git a/Easydict/App/AppDelegate.h b/Easydict/App/AppDelegate.h index d604f4d1b..2ecaff2c6 100644 --- a/Easydict/App/AppDelegate.h +++ b/Easydict/App/AppDelegate.h @@ -7,10 +7,7 @@ // #import -#import @interface AppDelegate : NSObject -@property (weak) IBOutlet SPUStandardUpdaterController *updaterController; - @end diff --git a/Easydict/App/AppDelegate.m b/Easydict/App/AppDelegate.m index 6e6efd49c..ccec0a435 100644 --- a/Easydict/App/AppDelegate.m +++ b/Easydict/App/AppDelegate.m @@ -7,19 +7,12 @@ // #import "AppDelegate.h" -#import "EZMenuItemManager.h" #import "EZShortcut.h" #import "MMCrash.h" -#import "EZWindowManager.h" -#import "EZLanguageManager.h" -#import "EZLog.h" -#import "EZSchemeParser.h" #import "AppDelegate+EZURLScheme.h" -#import -#import #import "Easydict-Swift.h" -@interface AppDelegate () +@interface AppDelegate () @end @@ -99,20 +92,4 @@ - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)applica return NO; } -#pragma mark - SUUpdaterDelegate - -- (NSString *)feedURLStringForUpdater:(SPUUpdater *)updater { - NSString *feedURLString = @"https://raw.githubusercontent.com/tisfeng/Easydict/main/appcast.xml"; -#if DEBUG - feedURLString = @"http://localhost:8000/appcast.xml"; -#endif - return feedURLString; -} - -#pragma mark - SPUStandardUserDriverDelegate - -- (BOOL)supportsGentleScheduledUpdateReminders { - return YES; -} - @end diff --git a/Easydict/App/Base.lproj/Main.storyboard b/Easydict/App/Base.lproj/Main.storyboard index 9df59d2cb..52009ade9 100644 --- a/Easydict/App/Base.lproj/Main.storyboard +++ b/Easydict/App/Base.lproj/Main.storyboard @@ -716,18 +716,8 @@ DQ - - - - - + - - - - - - @@ -799,7 +789,7 @@ DQ - + diff --git a/Easydict/Feature/Configuration/Configuration.swift b/Easydict/Feature/Configuration/Configuration.swift index f888889c2..c78b3f2b1 100644 --- a/Easydict/Feature/Configuration/Configuration.swift +++ b/Easydict/Feature/Configuration/Configuration.swift @@ -30,12 +30,6 @@ let kHideMenuBarIconKey = "EZConfiguration_kHideMenuBarIconKey" } } - var appDelegate = NSApp.delegate as? AppDelegate - - var updater: SPUUpdater? { - appDelegate?.updaterController.updater - } - @DefaultsWrapper(.firstLanguage) var firstLanguage: Language @@ -65,10 +59,10 @@ let kHideMenuBarIconKey = "EZConfiguration_kHideMenuBarIconKey" var automaticallyChecksForUpdates: Bool { get { - updater?.automaticallyChecksForUpdates ?? false + GlobalContext.shared.updaterController.updater.automaticallyDownloadsUpdates } set { - updater?.automaticallyChecksForUpdates = newValue + GlobalContext.shared.updaterController.updater.automaticallyDownloadsUpdates = newValue logSettings(["automatically_checks_for_updates": newValue]) } } diff --git a/Easydict/Feature/Configuration/EZConfiguration.h b/Easydict/Feature/Configuration/EZConfiguration.h index 310f47031..266797563 100644 --- a/Easydict/Feature/Configuration/EZConfiguration.h +++ b/Easydict/Feature/Configuration/EZConfiguration.h @@ -9,6 +9,7 @@ #import #import "EZLanguageManager.h" #import "EZLayoutManager.h" +#import NS_ASSUME_NONNULL_BEGIN @@ -84,6 +85,8 @@ typedef NS_ENUM(NSUInteger, EZAppearenceType) { @property (nonatomic, assign) EZAppearenceType appearance; +@property (nonatomic, strong, readonly) SPUUpdater *updater; + + (instancetype)shared; + (void)destroySharedInstance; diff --git a/Easydict/Feature/Configuration/EZConfiguration.m b/Easydict/Feature/Configuration/EZConfiguration.m index e1b40f69b..a3104745a 100644 --- a/Easydict/Feature/Configuration/EZConfiguration.m +++ b/Easydict/Feature/Configuration/EZConfiguration.m @@ -63,7 +63,7 @@ @interface EZConfiguration () @property (nonatomic, strong) AppDelegate *appDelegate; -@property (nonatomic, strong) SPUUpdater *updater; +@property (nonatomic, strong, readwrite) SPUUpdater *updater; @end @@ -142,12 +142,12 @@ - (BOOL)launchAtStartup { return launchAtStartup; } -- (BOOL)automaticallyChecksForUpdates { - return self.updater.automaticallyChecksForUpdates; +- (SPUUpdater *)updater { + return GlobalContext.shared.updaterController.updater; } -- (SPUUpdater *)updater { - return self.appDelegate.updaterController.updater; +- (BOOL)automaticallyChecksForUpdates { + return self.updater.automaticallyChecksForUpdates; } #pragma mark - setter diff --git a/Easydict/Feature/StatusItem/EZMenuItemManager.m b/Easydict/Feature/StatusItem/EZMenuItemManager.m index 8d9f3b017..9f40e3fc9 100644 --- a/Easydict/Feature/StatusItem/EZMenuItemManager.m +++ b/Easydict/Feature/StatusItem/EZMenuItemManager.m @@ -15,6 +15,8 @@ #import "EZRightClickDetector.h" #import "EZConfiguration.h" #import "Easydict-Swift.h" +#import +#import @interface EZMenuItemManager () @@ -181,6 +183,11 @@ - (IBAction)settingAction:(NSMenuItem *)sender { [EZPreferencesWindowController.shared show]; } +- (IBAction)checkForUpdateItem:(id)sender { + NSLog(@"checkForUpdate"); + [EZConfiguration.shared.updater checkForUpdates]; +} + - (IBAction)feedbackAction:(NSMenuItem *)sender { NSLog(@"反馈问题"); NSString *issueURL = [NSString stringWithFormat:@"%@/issues", EZGithubRepoEasydictURL]; diff --git a/Easydict/NewApp/EasydictApp.swift b/Easydict/NewApp/EasydictApp.swift index c81ba83f4..bb3e1be41 100644 --- a/Easydict/NewApp/EasydictApp.swift +++ b/Easydict/NewApp/EasydictApp.swift @@ -6,6 +6,7 @@ // Copyright © 2023 izual. All rights reserved. // +import Defaults import Sparkle import SwiftUI @@ -21,28 +22,14 @@ enum EasydictCmpatibilityEntry { } } -class SPUUpdaterHelper: NSObject, SPUUpdaterDelegate { - func feedURLString(for _: SPUUpdater) -> String? { - var feedURLString = "https://raw.githubusercontent.com/tisfeng/Easydict/main/appcast.xml" - #if DEBUG - feedURLString = "http://localhost:8000/appcast.xml" - #endif - return feedURLString - } -} - -class SPUUserDriverHelper: NSObject, SPUStandardUserDriverDelegate { - var supportsGentleScheduledUpdateReminders: Bool { - true - } -} - struct EasydictApp: App { @NSApplicationDelegateAdaptor - var delegate: AppDelegate + private var delegate: AppDelegate - @AppStorage(kHideMenuBarIconKey) - private var hideMenuBar = false + // Use `@Default` will cause a purple warning and continuously call `set` of it. + // I'm not sure why. Just leave `AppStorage` here. + @AppStorage(Defaults.Key.hideMenuBarIcon.name) + private var hideMenuBar = Defaults.Key.hideMenuBarIcon.defaultValue private var menuBarImage: String { #if DEBUG @@ -52,22 +39,10 @@ struct EasydictApp: App { #endif } - let userDriverHelper = SPUUserDriverHelper() - let upadterHelper = SPUUpdaterHelper() - - private let updaterController: SPUStandardUpdaterController - - init() { - // 参考 https://sparkle-project.org/documentation/programmatic-setup/ - // If you want to start the updater manually, pass false to startingUpdater and call .startUpdater() later - // This is where you can also pass an updater delegate if you need one - updaterController = SPUStandardUpdaterController(startingUpdater: true, updaterDelegate: upadterHelper, userDriverDelegate: userDriverHelper) - } - var body: some Scene { if #available(macOS 13, *) { MenuBarExtra(isInserted: $hideMenuBar.toggledValue) { - MenuItemView(updater: updaterController.updater) + MenuItemView() } label: { Label { Text("Easydict") diff --git a/Easydict/NewApp/Utility/GlobalContext.swift b/Easydict/NewApp/Utility/GlobalContext.swift new file mode 100644 index 000000000..557c22ae1 --- /dev/null +++ b/Easydict/NewApp/Utility/GlobalContext.swift @@ -0,0 +1,43 @@ +// +// GlobalContext.swift +// Easydict +// +// Created by 戴藏龙 on 2024/1/25. +// Copyright © 2024 izual. All rights reserved. +// + +import Foundation +import Sparkle + +@objcMembers +class GlobalContext: NSObject { + static let shared = GlobalContext() + + let updaterController: SPUStandardUpdaterController + + private let updaterHelper: SPUUpdaterHelper + private let userDriverHelper: SPUUserDriverHelper + + override init() { + updaterHelper = SPUUpdaterHelper() + userDriverHelper = SPUUserDriverHelper() + + updaterController = SPUStandardUpdaterController(startingUpdater: true, updaterDelegate: updaterHelper, userDriverDelegate: userDriverHelper) + } + + class SPUUpdaterHelper: NSObject, SPUUpdaterDelegate { + func feedURLString(for _: SPUUpdater) -> String? { + var feedURLString = "https://raw.githubusercontent.com/tisfeng/Easydict/main/appcast.xml" + #if DEBUG + feedURLString = "http://localhost:8000/appcast.xml" + #endif + return feedURLString + } + } + + class SPUUserDriverHelper: NSObject, SPUStandardUserDriverDelegate { + var supportsGentleScheduledUpdateReminders: Bool { + true + } + } +} diff --git a/Easydict/NewApp/View/MenuItemView.swift b/Easydict/NewApp/View/MenuItemView.swift index 5f25919b1..65a264c59 100644 --- a/Easydict/NewApp/View/MenuItemView.swift +++ b/Easydict/NewApp/View/MenuItemView.swift @@ -13,21 +13,19 @@ import ZipArchive @available(macOS 13, *) final class MenuItemStore: ObservableObject { @Published var canCheckForUpdates = false - var updater: SPUUpdater - init(updater: SPUUpdater) { - self.updater = updater - self.updater.publisher(for: \.canCheckForUpdates) + + init() { + GlobalContext.shared + .updaterController + .updater + .publisher(for: \.canCheckForUpdates) .assign(to: &$canCheckForUpdates) } } @available(macOS 13, *) struct MenuItemView: View { - @ObservedObject var store: MenuItemStore - - init(updater: SPUUpdater) { - store = MenuItemStore(updater: updater) - } + @ObservedObject private var store = MenuItemStore() var body: some View { // ️.menuBarExtraStyle为 .menu 时某些控件可能会失效 ,只能显示内容(按照菜单项高度、图像以 template 方式渲染)无法交互 ,比如 Stepper、Slider 等,像基本的 Button、Text、Divider、Image 等还是能正常显示的。 @@ -173,7 +171,7 @@ struct MenuItemView: View { private var checkUpdateItem: some View { Button("check_updates") { NSLog("检查更新") - store.updater.checkForUpdates() + GlobalContext.shared.updaterController.updater.checkForUpdates() }.disabled(!store.canCheckForUpdates) } @@ -225,5 +223,5 @@ struct MenuItemView: View { @available(macOS 13, *) #Preview { - MenuItemView(updater: SPUStandardUpdaterController(startingUpdater: true, updaterDelegate: nil, userDriverDelegate: nil).updater) + MenuItemView() }