在 iOS "monitor" NSUserDefaults 读写
On iOS "monitor" NSUserDefaults read and writes
在我的 iOS 项目中,我正在使用第 3 方库 (Google VR),它向 NSUserDefaults
.
读取和写入内容
我知道我可以读取和打印所有用户默认设置(通过类似
NSArray *keys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys];
for(NSString* key in keys){
// your code here
NSLog(@"value: %@ forKey: %@",[[NSUserDefaults standardUserDefaults] valueForKey:key],key);
}
我需要的是查看图书馆正在寻找什么而不是找不到。
基本上,库通过检查 userdefaults 密钥来检查它之前是否已经完成配置(与纸板耳机配对)。我想知道它什么时候发生以及它是什么。
我知道一种方法是进行比较,在配对前后打印所有用户默认值并查看发生了什么变化,但我想知道是否有监控 NSUserDefaults
读取调用的通用方法。
Method swizzling,听起来像是一个可能的解决方案,但我不太确定它是如何工作的。
编辑: 作为记录,我使用了下面@BlackM 的答案,发现 Google VR for Unity,在 iOS 上寻找com.google.cardboard.sdk.DeviceParamsAndTime
查看是否配置了耳机。
我设法用 method swizzling 实现了它:
#import <objc/runtime.h>
@implementation NSUserDefaults (Read)
+(void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
//Swizzling objectForKey
SEL originalSelectorVWA = @selector(objectForKey:);
SEL swizzledSelectorVWA = @selector(swizzled_objectForKey:);
Method originalMethodVWA = class_getInstanceMethod(class, originalSelectorVWA);
Method swizzledMethodVWA = class_getInstanceMethod(class, swizzledSelectorVWA);
BOOL didAddMethodVWA =
class_addMethod(class,
originalSelectorVWA,
method_getImplementation(swizzledMethodVWA),
method_getTypeEncoding(swizzledMethodVWA));
if (didAddMethodVWA) {
class_replaceMethod(class,
swizzledSelectorVWA,
method_getImplementation(originalMethodVWA),
method_getTypeEncoding(originalMethodVWA));
} else {
method_exchangeImplementations(originalMethodVWA, swizzledMethodVWA);
}
});
}
#pragma mark - Method Swizzling
- (id)swizzled_objectForKey:(NSString *)defaultName {
id data = [self swizzled_objectForKey:defaultName];
if (!data) {
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:defaultName forKey:@"key"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"readNSUserDefaults" object:nil userInfo:infoDict];
}
return data;
}
@end
在你的控制器中:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *valueToSave = @"someValue";
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:@"someKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readNSUSerDefaults:) name:@"readNSUserDefaults" object:nil];
[[NSUserDefaults standardUserDefaults] stringForKey:@"someKey"];
[[NSUserDefaults standardUserDefaults] stringForKey:@"thisKeyDoesntExistKey"];
}
-(void)readNSUSerDefaults:(NSNotification*)notification {
NSString *key = [notification.userInfo objectForKey:@"key"];
NSLog(@"Read key %@ returned nil NSUserDefaults",key);
}
在我的 iOS 项目中,我正在使用第 3 方库 (Google VR),它向 NSUserDefaults
.
我知道我可以读取和打印所有用户默认设置(通过类似
NSArray *keys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys];
for(NSString* key in keys){
// your code here
NSLog(@"value: %@ forKey: %@",[[NSUserDefaults standardUserDefaults] valueForKey:key],key);
}
我需要的是查看图书馆正在寻找什么而不是找不到。
基本上,库通过检查 userdefaults 密钥来检查它之前是否已经完成配置(与纸板耳机配对)。我想知道它什么时候发生以及它是什么。
我知道一种方法是进行比较,在配对前后打印所有用户默认值并查看发生了什么变化,但我想知道是否有监控 NSUserDefaults
读取调用的通用方法。
Method swizzling,听起来像是一个可能的解决方案,但我不太确定它是如何工作的。
编辑: 作为记录,我使用了下面@BlackM 的答案,发现 Google VR for Unity,在 iOS 上寻找com.google.cardboard.sdk.DeviceParamsAndTime
查看是否配置了耳机。
我设法用 method swizzling 实现了它:
#import <objc/runtime.h>
@implementation NSUserDefaults (Read)
+(void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
//Swizzling objectForKey
SEL originalSelectorVWA = @selector(objectForKey:);
SEL swizzledSelectorVWA = @selector(swizzled_objectForKey:);
Method originalMethodVWA = class_getInstanceMethod(class, originalSelectorVWA);
Method swizzledMethodVWA = class_getInstanceMethod(class, swizzledSelectorVWA);
BOOL didAddMethodVWA =
class_addMethod(class,
originalSelectorVWA,
method_getImplementation(swizzledMethodVWA),
method_getTypeEncoding(swizzledMethodVWA));
if (didAddMethodVWA) {
class_replaceMethod(class,
swizzledSelectorVWA,
method_getImplementation(originalMethodVWA),
method_getTypeEncoding(originalMethodVWA));
} else {
method_exchangeImplementations(originalMethodVWA, swizzledMethodVWA);
}
});
}
#pragma mark - Method Swizzling
- (id)swizzled_objectForKey:(NSString *)defaultName {
id data = [self swizzled_objectForKey:defaultName];
if (!data) {
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:defaultName forKey:@"key"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"readNSUserDefaults" object:nil userInfo:infoDict];
}
return data;
}
@end
在你的控制器中:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *valueToSave = @"someValue";
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:@"someKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readNSUSerDefaults:) name:@"readNSUserDefaults" object:nil];
[[NSUserDefaults standardUserDefaults] stringForKey:@"someKey"];
[[NSUserDefaults standardUserDefaults] stringForKey:@"thisKeyDoesntExistKey"];
}
-(void)readNSUSerDefaults:(NSNotification*)notification {
NSString *key = [notification.userInfo objectForKey:@"key"];
NSLog(@"Read key %@ returned nil NSUserDefaults",key);
}