2016-11-17 2 views
1

В моем проекте iOS я использую стороннюю библиотеку (Google VR), которая читает и записывает материал в NSUserDefaults.На iOS «monitor» NSUserDefaults читает и пишет

Я знаю, что могу читать и печатать все пользователя по умолчанию (что-то вроде

NSArray *keys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys]; 

for(NSString* key in keys){ 
    // your code here 
    NSLog(@"value: %@ forKey: %@",[[NSUserDefaults standardUserDefaults] valueForKey:key],key); 
} 

Что мне нужно, чтобы увидеть, что библиотека ищет и не не найти.
В принципе, проверки библиотеки если он выполнил конфигурацию до (сопряжение с картонной гарнитурой), проверив ключ userdefaults. Я хочу знать, когда это произойдет и что такое ket.

Я понимаю, что один способ - это сделать diff, распечатать все пользовательские значения по умолчанию до и после спаривания и посмотреть, что изменилось, но я хочу знать, есть ли общий wa y для отслеживания вызовов NSUserDefaults.

Метод swizzling, звучит как возможное решение, но я не совсем уверен, как это будет работать.

EDIT: для записи, я использовал ответ на @BlackM ниже, и выяснили, что Google VR для Unity, на IOS ищет com.google.cardboard.sdk.DeviceParamsAndTime, чтобы проверить, если он настроил гарнитуру или нет.

ответ

2

мне удается реализовать с помощью метода 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); 
} 
+1

Это только для записи, не читает. – rmaddy

+1

Комментарий выше был до редактирования, теперь он работает для чтения. @rmaddy был прав до этого последнего изменения. – Ali

Смежные вопросы