简介
Sparkle 是 macOS 平台上一个优秀的自动更新框架。虽然 Sparkle 提供了默认的更新界面,但有时我们需要自定义更新弹窗以匹配应用的设计风格。本文将介绍如何使用 Sparkle 实现自定义更新界面。
实现步骤
1. 创建自定义更新窗口
首先需要创建一个继承自 NSPanel
的自定义窗口类:
swift
class UpdateNotificationWindow: NSPanel {
private let stackView = NSStackView()
private let titleLabel = NSTextField()
private let messageLabel = NSTextField()
private let progressBar = NSProgressIndicator()
private var buttons: [NSButton] = []
init() {
super.init(contentRect: NSRect(x: 0, y: 0, width: 320, height: 240),
styleMask: [.nonactivatingPanel, .titled, .fullSizeContentView],
backing: .buffered,
defer: false)
setupWindow()
setupUI()
}
}
2. 实现自定义用户驱动
需要创建一个实现 SPUUserDriver
协议的类来处理更新流程中的各个状态:
swift
final class CustomUserDriver: NSObject, SPUUserDriver {
private var notificationWindow: UpdateNotificationWindow?
// 检查更新
func showUserInitiatedUpdateCheck(cancellation: @escaping () -> Void) {
ensureNotificationWindow().showChecking {
cancellation()
}
}
// 找到更新
func showUpdateFound(with appcastItem: SUAppcastItem, state: SPUUserUpdateState) async -> SPUUserUpdateChoice {
return await withCheckedContinuation { continuation in
DispatchQueue.main.async {
self.ensureNotificationWindow().showUpdateFound { updateChoice, type in
continuation.resume(returning: updateChoice)
}
}
}
}
// 显示下载进度
func showDownloadDidReceiveData(ofLength length: UInt64) {
let progress = Double(currentProgress) / Double(downloadSize) * 100
ensureNotificationWindow().showDownloadProgress(progress)
}
}
3. 配置更新控制器
创建一个更新控制器类来管理 Sparkle 更新器:
swift
final class UpdateController {
static let shared = UpdateController()
let updater: SPUUpdater
private let userDriver: CustomUserDriver
private init() {
userDriver = CustomUserDriver()
updater = SPUUpdater(hostBundle: Bundle.main,
applicationBundle: Bundle.main,
userDriver: userDriver,
delegate: nil)
try? updater.start()
updater.automaticallyChecksForUpdates = true
updater.updateCheckInterval = 3600 * 6
updater.setFeedURL(URL(string: "https://your-update-url/appcast.xml"))
}
}
主要功能
1. 检查更新界面
- 显示检查更新状态
- 提供取消按钮
2. 发现更新界面
- 显示新版本信息
- 提供"立即安装"和"下次启动时安装"选项
3. 下载进度界面
- 显示实时下载进度
- 进度条可视化展示
4. 安装准备界面
- 提示用户重启应用进行安装
- 显示安装确认按钮
界面美化
为了让更新窗口更美观,我们可以:
- 添加圆角和阴影:
swift
contentView?.layer?.cornerRadius = 12
hasShadow = true
- 自定义按钮样式:
swift
private func createStyledButton(title: String, isPrimary: Bool = false) -> NSButton {
let button = NSButton(title: title, target: nil, action: nil)
button.layer?.cornerRadius = 6
if isPrimary {
button.contentTintColor = .white
button.layer?.backgroundColor = NSColor.controlAccentColor.cgColor
} else {
button.contentTintColor = .black
button.layer?.backgroundColor = NSColor.controlBackgroundColor.cgColor
}
return button
}
总结
通过自定义 Sparkle 的更新界面,我们可以:
- 提供与应用一致的设计风格
- 更好地控制更新流程
- 提供更好的用户体验
完整的实现代码可以参考上面的示例。通过这种方式,我们可以为 macOS 应用提供一个既美观又实用的自动更新体验。
注意事项
- 确保正确处理所有更新状态
- 适当处理错误情况
- 保持界面响应性
- 提供清晰的用户反馈
希望这篇文章对你实现自定义 Sparkle 更新界面有所帮助!