语记手表版 v0.1:一键录音、WatchConnectivity 传输、表盘复杂功能、iPhone 接收转写
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import Foundation
|
||||
import WatchConnectivity
|
||||
import WidgetKit
|
||||
|
||||
/// 手表端会话管理:激活 WCSession、传录音文件到 iPhone、维护今日速记数并刷新复杂功能。
|
||||
@MainActor
|
||||
final class WatchSessionManager: NSObject, ObservableObject, WCSessionDelegate {
|
||||
static let todayCountKey = "yujiTodayCount"
|
||||
static let todayDateKey = "yujiTodayDate"
|
||||
|
||||
@Published var transferState = ""
|
||||
@Published var todayCount = 0
|
||||
|
||||
private var completions: [String: (Result<Void, Error>) -> Void] = [:]
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
todayCount = Self.loadTodayCount()
|
||||
if WCSession.isSupported() {
|
||||
let session = WCSession.default
|
||||
session.delegate = self
|
||||
session.activate()
|
||||
}
|
||||
}
|
||||
|
||||
/// 今日速记数:按自然日归零,存在手表本地 UserDefaults
|
||||
static func loadTodayCount() -> Int {
|
||||
let defaults = UserDefaults.standard
|
||||
let today = Calendar.current.startOfDay(for: Date())
|
||||
if let saved = defaults.object(forKey: todayDateKey) as? Date,
|
||||
Calendar.current.isDate(saved, inSameDayAs: today) {
|
||||
return defaults.integer(forKey: todayCountKey)
|
||||
}
|
||||
defaults.set(today, forKey: todayDateKey)
|
||||
defaults.set(0, forKey: todayCountKey)
|
||||
return 0
|
||||
}
|
||||
|
||||
private func bumpTodayCount() {
|
||||
todayCount = Self.loadTodayCount() + 1
|
||||
UserDefaults.standard.set(todayCount, forKey: todayCountKey)
|
||||
WidgetCenter.shared.reloadAllTimelines()
|
||||
}
|
||||
|
||||
/// 传录音文件到 iPhone,完成后回调(成功时今日数 +1 并刷新复杂功能)
|
||||
func transfer(url: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard WCSession.isSupported(), WCSession.default.activationState == .activated else {
|
||||
completion(.failure(NSError(domain: "YuJiWatch", code: 1, userInfo: [NSLocalizedDescriptionKey: "手表与 iPhone 未连接,录音先存在手表上,连上后会自动重传。"])))
|
||||
return
|
||||
}
|
||||
let transfer = WCSession.default.transferFile(url, metadata: ["createdAt": Date().timeIntervalSince1970])
|
||||
completions[transfer.file.fileURL.lastPathComponent] = completion
|
||||
transferState = "正在传到 iPhone…"
|
||||
}
|
||||
|
||||
// MARK: - WCSessionDelegate
|
||||
|
||||
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
|
||||
// 激活完成即可传文件,无需额外处理
|
||||
}
|
||||
|
||||
func session(_ session: WCSession, didFinish fileTransfer: WCSessionFileTransfer, error: Error?) {
|
||||
let key = fileTransfer.file.fileURL.lastPathComponent
|
||||
guard let completion = completions.removeValue(forKey: key) else { return }
|
||||
if let error {
|
||||
transferState = "传输失败:\(error.localizedDescription)"
|
||||
completion(.failure(error))
|
||||
} else {
|
||||
transferState = "已传到 iPhone"
|
||||
bumpTodayCount()
|
||||
completion(.success(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user