feat(ios): 添加用药计划Widget小组件支持
- 创建medicineExtension小组件,支持iOS桌面显示用药计划 - 实现App Group数据共享机制,支持主应用与小组件数据同步 - 添加AppGroupUserDefaultsManager原生模块,提供跨应用数据访问能力 - 添加WidgetManager和WidgetCenterHelper,实现小组件刷新控制 - 在medications页面和Redux store中集成小组件数据同步逻辑 - 支持实时同步今日用药状态(待服用/已服用/已错过)到小组件 - 配置App Group entitlements (group.com.anonymous.digitalpilates) - 更新Xcode项目配置,添加WidgetKit和SwiftUI框架支持
This commit is contained in:
163
ios/AppGroupUserDefaultsManager.m
Normal file
163
ios/AppGroupUserDefaultsManager.m
Normal file
@@ -0,0 +1,163 @@
|
||||
//
|
||||
// AppGroupUserDefaultsManager.m
|
||||
// OutLive
|
||||
//
|
||||
// Created by AI Assistant on 2025/11/13.
|
||||
//
|
||||
|
||||
#import "AppGroupUserDefaultsManager.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// App Group标识符
|
||||
static NSString * const APP_GROUP_ID = @"group.com.anonymous.digitalpilates";
|
||||
|
||||
@implementation AppGroupUserDefaultsManager
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents {
|
||||
return @[];
|
||||
}
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSUserDefaults *)getAppGroupUserDefaults {
|
||||
return [[NSUserDefaults alloc] initWithSuiteName:APP_GROUP_ID];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setString:(NSString *)groupId
|
||||
key:(NSString *)key
|
||||
value:(NSString *)value
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
|
||||
@try {
|
||||
NSUserDefaults *defaults = [self getAppGroupUserDefaults];
|
||||
if (defaults) {
|
||||
[defaults setObject:value forKey:key];
|
||||
[defaults synchronize];
|
||||
resolve(nil);
|
||||
} else {
|
||||
reject(@"APP_GROUP_ERROR", @"Failed to access App Group UserDefaults", nil);
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
reject(@"SET_STRING_ERROR", exception.reason, nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getString:(NSString *)groupId
|
||||
key:(NSString *)key
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
|
||||
@try {
|
||||
NSUserDefaults *defaults = [self getAppGroupUserDefaults];
|
||||
if (defaults) {
|
||||
NSString *value = [defaults stringForKey:key];
|
||||
resolve(value ?: [NSNull null]);
|
||||
} else {
|
||||
reject(@"APP_GROUP_ERROR", @"Failed to access App Group UserDefaults", nil);
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
reject(@"GET_STRING_ERROR", exception.reason, nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setNumber:(NSString *)groupId
|
||||
key:(NSString *)key
|
||||
value:(nonnull NSNumber *)value
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
|
||||
@try {
|
||||
NSUserDefaults *defaults = [self getAppGroupUserDefaults];
|
||||
if (defaults) {
|
||||
[defaults setObject:value forKey:key];
|
||||
[defaults synchronize];
|
||||
resolve(nil);
|
||||
} else {
|
||||
reject(@"APP_GROUP_ERROR", @"Failed to access App Group UserDefaults", nil);
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
reject(@"SET_NUMBER_ERROR", exception.reason, nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getNumber:(NSString *)groupId
|
||||
key:(NSString *)key
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
|
||||
@try {
|
||||
NSUserDefaults *defaults = [self getAppGroupUserDefaults];
|
||||
if (defaults) {
|
||||
NSNumber *value = [defaults objectForKey:key];
|
||||
resolve(value ?: @0);
|
||||
} else {
|
||||
reject(@"APP_GROUP_ERROR", @"Failed to access App Group UserDefaults", nil);
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
reject(@"GET_NUMBER_ERROR", exception.reason, nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(removeKey:(NSString *)groupId
|
||||
key:(NSString *)key
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
|
||||
@try {
|
||||
NSUserDefaults *defaults = [self getAppGroupUserDefaults];
|
||||
if (defaults) {
|
||||
[defaults removeObjectForKey:key];
|
||||
[defaults synchronize];
|
||||
resolve(nil);
|
||||
} else {
|
||||
reject(@"APP_GROUP_ERROR", @"Failed to access App Group UserDefaults", nil);
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
reject(@"REMOVE_KEY_ERROR", exception.reason, nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setArray:(NSString *)groupId
|
||||
key:(NSString *)key
|
||||
value:(NSArray *)value
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
|
||||
@try {
|
||||
NSUserDefaults *defaults = [self getAppGroupUserDefaults];
|
||||
if (defaults) {
|
||||
[defaults setObject:value forKey:key];
|
||||
[defaults synchronize];
|
||||
resolve(nil);
|
||||
} else {
|
||||
reject(@"APP_GROUP_ERROR", @"Failed to access App Group UserDefaults", nil);
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
reject(@"SET_ARRAY_ERROR", exception.reason, nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getArray:(NSString *)groupId
|
||||
key:(NSString *)key
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
|
||||
@try {
|
||||
NSUserDefaults *defaults = [self getAppGroupUserDefaults];
|
||||
if (defaults) {
|
||||
NSArray *value = [defaults arrayForKey:key];
|
||||
resolve(value ?: [NSNull null]);
|
||||
} else {
|
||||
reject(@"APP_GROUP_ERROR", @"Failed to access App Group UserDefaults", nil);
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
reject(@"GET_ARRAY_ERROR", exception.reason, nil);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user