Ice状态恢复:NSRestorableState管理

Ice状态恢复:NSRestorableState管理

【免费下载链接】Ice Powerful menu bar manager for macOS 【免费下载链接】Ice 项目地址: https://gitcode.com/GitHub_Trending/ice/Ice

概述

Ice作为macOS菜单栏管理工具,其状态恢复机制是确保用户体验连续性的核心功能。通过NSRestorableState协议和UserDefaults的组合,Ice实现了应用状态的高效持久化和恢复,让用户在应用重启后能够无缝继续之前的工作流程。

状态恢复架构设计

核心组件关系

mermaid

状态持久化层次

层级组件数据类型持久化方式
应用级AppState运行时状态内存管理
设置级SettingsManager用户配置UserDefaults + JSON编码
界面级MenuBarManager布局信息UserDefaults
外观级AppearanceManager视觉配置UserDefaults + Codable

UserDefaults集成实现

键值定义策略

Ice采用类型安全的键值定义方式,在Defaults.swift中集中管理所有UserDefaults键:

enum Defaults {
    enum Key: String {
        // 通用设置
        case showIceIcon = "ShowIceIcon"
        case useIceBar = "UseIceBar"
        case showOnClick = "ShowOnClick"
        
        // 快捷键设置
        case hotkeys = "Hotkeys"
        
        // 高级设置
        case hideApplicationMenus = "HideApplicationMenus"
        
        // 菜单栏外观
        case menuBarAppearanceConfigurationV2 = "MenuBarAppearanceConfigurationV2"
        
        // 迁移标记
        case hasMigrated0_8_0 = "hasMigrated0_8_0"
    }
}

类型安全访问器

Ice提供了类型安全的访问方法,避免直接操作UserDefaults带来的类型错误:

static func bool(forKey key: Key) -> Bool {
    UserDefaults.standard.bool(forKey: key.rawValue)
}

static func set(_ value: Any?, forKey key: Key) {
    UserDefaults.standard.set(value, forKey: key.rawValue)
}

static func ifPresent<Value>(key: Key, assign value: inout Value) {
    if let found = object(forKey: key) as? Value {
        value = found
    }
}

设置管理器实现

GeneralSettingsManager状态管理

@MainActor
final class GeneralSettingsManager: ObservableObject {
    @Published var showIceIcon = true
    @Published var useIceBar = false
    @Published var showOnClick = true
    
    private let encoder = JSONEncoder()
    private let decoder = JSONDecoder()
    
    func performSetup() {
        loadInitialState()
        configureCancellables()
    }
    
    private func loadInitialState() {
        Defaults.ifPresent(key: .showIceIcon, assign: &showIceIcon)
        Defaults.ifPresent(key: .useIceBar, assign: &useIceBar)
        Defaults.ifPresent(key: .showOnClick, assign: &showOnClick)
    }
    
    private func configureCancellables() {
        $showIceIcon
            .receive(on: DispatchQueue.main)
            .sink { showIceIcon in
                Defaults.set(showIceIcon, forKey: .showIceIcon)
            }
            .store(in: &cancellables)
    }
}

复杂对象序列化

对于复杂对象如ControlItemImageSet,Ice使用JSON编码进行序列化:

$iceIcon
    .receive(on: DispatchQueue.main)
    .sink { [weak self] iceIcon in
        guard let self else { return }
        do {
            let data = try encoder.encode(iceIcon)
            Defaults.set(data, forKey: .iceIcon)
        } catch {
            Logger.error("Error encoding Ice icon: \(error)")
        }
    }
    .store(in: &cancellables)

应用状态恢复流程

启动序列

mermaid

权限检查与状态恢复

func applicationDidFinishLaunching(_ notification: Notification) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        switch appState.permissionsManager.permissionsState {
        case .hasAllPermissions, .hasRequiredPermissions:
            appState.performSetup() // 完整状态恢复
        case .missingPermissions:
            appState.openPermissionsWindow() // 延迟状态恢复
        }
    }
}

高级状态管理特性

响应式状态绑定

Ice使用Combine框架实现响应式状态管理,确保UI与数据状态实时同步:

private func configureCancellables() {
    var c = Set<AnyCancellable>()
    
    $showOnHover
        .receive(on: DispatchQueue.main)
        .sink { showOnHover in
            Defaults.set(showOnHover, forKey: .showOnHover)
        }
        .store(in: &c)
    
    $itemSpacingOffset
        .receive(on: DispatchQueue.main)
        .sink { [weak appState] offset in
            Defaults.set(offset, forKey: .itemSpacingOffset)
            appState?.spacingManager.offset = Int(offset)
        }
        .store(in: &c)
}

迁移管理

Ice包含完善的迁移机制,处理不同版本间的状态格式变化:

enum Key: String {
    case hasMigrated0_8_0 = "hasMigrated0_8_0"
    case hasMigrated0_10_0 = "hasMigrated0_10_0"
    case hasMigrated0_10_1 = "hasMigrated0_10_1"
    case hasMigrated0_11_10 = "hasMigrated0_11_10"
}

最佳实践与设计模式

状态管理设计模式

模式应用场景Ice实现示例
ObservableObject响应式状态管理@Published var showIceIcon
BindingExposable双向数据绑定extension AppState: BindingExposable
Sink订阅状态持久化$showIceIcon.sink { ... }
延迟加载性能优化DispatchQueue.main.asyncAfter

错误处理与日志

Ice实现了完善的错误处理和日志记录:

if let data = Defaults.data(forKey: .iceIcon) {
    do {
        iceIcon = try decoder.decode(ControlItemImageSet.self, from: data)
    } catch {
        Logger.generalSettingsManager.error("Error decoding Ice icon: \(error)")
    }
}

性能优化策略

延迟状态恢复

Ice采用延迟状态恢复策略,避免阻塞主线程:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    appState.performSetup()
}

批量状态操作

通过Combine的debounce操作符减少不必要的持久化操作:

settingsWindow.publisher(for: \.isVisible)
    .debounce(for: 0.05, scheduler: DispatchQueue.main)
    .sink { isVisible in
        navigationState.isSettingsPresented = isVisible
    }

总结

Ice的状态恢复机制通过NSRestorableState协议和UserDefaults的有机结合,实现了高效、可靠的应用状态管理。其设计特点包括:

  1. 类型安全:通过枚举和泛型方法确保类型安全
  2. 响应式编程:利用Combine框架实现实时状态同步
  3. 模块化设计:各管理器职责单一,易于维护
  4. 错误恢复:完善的错误处理和日志记录
  5. 性能优化:延迟加载和批量操作减少性能开销

这种设计确保了Ice在提供丰富功能的同时,保持了出色的用户体验和系统性能。

【免费下载链接】Ice Powerful menu bar manager for macOS 【免费下载链接】Ice 项目地址: https://gitcode.com/GitHub_Trending/ice/Ice

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值