- 在useWaterData中统一处理数据变更后的Widget同步逻辑 - 新增数组类型数据存取方法支持更复杂数据结构 - 重构Widget UI为圆形进度条设计,提升视觉体验 - 修复数据同步时可能存在的竞态条件问题 - 优化错误处理,确保Widget同步失败不影响主功能
146 lines
4.3 KiB
Swift
146 lines
4.3 KiB
Swift
//
|
|
// AppGroupUserDefaults.swift
|
|
// digitalpilates
|
|
//
|
|
// Native module for accessing App Group UserDefaults
|
|
// Allows sharing data between main app and widget
|
|
//
|
|
|
|
import Foundation
|
|
import React
|
|
|
|
@objc(AppGroupUserDefaults)
|
|
class AppGroupUserDefaults: NSObject, RCTBridgeModule {
|
|
|
|
static func moduleName() -> String! {
|
|
return "AppGroupUserDefaults"
|
|
}
|
|
|
|
static func requiresMainQueueSetup() -> Bool {
|
|
return false
|
|
}
|
|
|
|
// MARK: - String Methods
|
|
|
|
@objc
|
|
func setString(_ groupId: String, key: String, value: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
DispatchQueue.global(qos: .background).async {
|
|
guard let userDefaults = UserDefaults(suiteName: groupId) else {
|
|
rejecter("ERROR", "Failed to create UserDefaults with suite name: \(groupId)", nil)
|
|
return
|
|
}
|
|
|
|
userDefaults.set(value, forKey: key)
|
|
userDefaults.synchronize()
|
|
|
|
DispatchQueue.main.async {
|
|
resolver(nil)
|
|
}
|
|
}
|
|
}
|
|
|
|
@objc
|
|
func getString(_ groupId: String, key: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
DispatchQueue.global(qos: .background).async {
|
|
guard let userDefaults = UserDefaults(suiteName: groupId) else {
|
|
rejecter("ERROR", "Failed to create UserDefaults with suite name: \(groupId)", nil)
|
|
return
|
|
}
|
|
|
|
let value = userDefaults.string(forKey: key)
|
|
|
|
DispatchQueue.main.async {
|
|
resolver(value)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Number Methods
|
|
|
|
@objc
|
|
func setNumber(_ groupId: String, key: String, value: NSNumber, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
DispatchQueue.global(qos: .background).async {
|
|
guard let userDefaults = UserDefaults(suiteName: groupId) else {
|
|
rejecter("ERROR", "Failed to create UserDefaults with suite name: \(groupId)", nil)
|
|
return
|
|
}
|
|
|
|
userDefaults.set(value, forKey: key)
|
|
userDefaults.synchronize()
|
|
|
|
DispatchQueue.main.async {
|
|
resolver(nil)
|
|
}
|
|
}
|
|
}
|
|
|
|
@objc
|
|
func getNumber(_ groupId: String, key: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
DispatchQueue.global(qos: .background).async {
|
|
guard let userDefaults = UserDefaults(suiteName: groupId) else {
|
|
rejecter("ERROR", "Failed to create UserDefaults with suite name: \(groupId)", nil)
|
|
return
|
|
}
|
|
|
|
let value = userDefaults.object(forKey: key) as? NSNumber ?? NSNumber(value: 0)
|
|
|
|
DispatchQueue.main.async {
|
|
resolver(value)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Array Methods
|
|
|
|
@objc
|
|
func setArray(_ groupId: String, key: String, value: [Any], resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
DispatchQueue.global(qos: .background).async {
|
|
guard let userDefaults = UserDefaults(suiteName: groupId) else {
|
|
rejecter("ERROR", "Failed to create UserDefaults with suite name: \(groupId)", nil)
|
|
return
|
|
}
|
|
|
|
userDefaults.set(value, forKey: key)
|
|
userDefaults.synchronize()
|
|
|
|
DispatchQueue.main.async {
|
|
resolver(nil)
|
|
}
|
|
}
|
|
}
|
|
|
|
@objc
|
|
func getArray(_ groupId: String, key: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
DispatchQueue.global(qos: .background).async {
|
|
guard let userDefaults = UserDefaults(suiteName: groupId) else {
|
|
rejecter("ERROR", "Failed to create UserDefaults with suite name: \(groupId)", nil)
|
|
return
|
|
}
|
|
|
|
let value = userDefaults.array(forKey: key)
|
|
|
|
DispatchQueue.main.async {
|
|
resolver(value)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Remove Key Method
|
|
|
|
@objc
|
|
func removeKey(_ groupId: String, key: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
|
|
DispatchQueue.global(qos: .background).async {
|
|
guard let userDefaults = UserDefaults(suiteName: groupId) else {
|
|
rejecter("ERROR", "Failed to create UserDefaults with suite name: \(groupId)", nil)
|
|
return
|
|
}
|
|
|
|
userDefaults.removeObject(forKey: key)
|
|
userDefaults.synchronize()
|
|
|
|
DispatchQueue.main.async {
|
|
resolver(nil)
|
|
}
|
|
}
|
|
}
|
|
} |