CSMigrator.h 2.73 KB
//
//  CSMigrator.h
//  CocoaSettings
//
//  Created by Yunpeng Li on 2018/5/14.
//  Copyright © 2018年 Baidu. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CocoaSettings/NSDictionary+CSJSONKeyPath.h>

#define CSMigrateUserDefaultsStart \
NSDictionary *willBeMigratedData = nil; \
NSMutableArray *migratedKeys = nil;\
NSMutableDictionary *migratingData = [[NSMutableDictionary alloc] init]

#define CSMigrateUserDefaultsEnd \
_CSMigrateImportData; \
[[NSUserDefaults standardUserDefaults] synchronize]

#define CSMigrateDictionaryStart(DATA) \
NSDictionary *willBeMigratedData = DATA; \
NSMutableArray *migratedKeys = [[NSMutableArray alloc] init]; \
NSMutableDictionary *migratingData = [[NSMutableDictionary alloc] init]

#define CSMigrateDictionaryEnd \
_CSMigrateImportData; \
return migratedKeys

#define _CSMigrateImportData \
do {\
    [migratingData enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull layerIdentifier, NSDictionary *layerData, BOOL * _Nonnull stop) {\
        CSDataLayer *layer = [[CocoaSettings sharedInstance] layerForIdentifier:layerIdentifier];\
        [layerData enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, NSDictionary * values, BOOL * _Nonnull stop) {\
            [layer loadSettingsFromDictionary:values forClass:NSClassFromString(key)];\
        }];\
    }];\
} while(0)

#define CSMigrateToModified(KEY, CLASS, PROPERTY) _CSMigrateTo(KEY, kCSDataLayerIdentifierModified, CLASS, @keypath([CLASS defaults], PROPERTY))



/**
 将值写入migratingData, 并将key计入migratedKeys

 @param KEY 迁移前对应的Key(可以是JSONPathKey也可以是UserDefault的Key)
 @param LAYER_IDENTIFIER 对应Layer的identifier
 @param CLASS 目标类
 @param SETTINGS_KEY key
 */
#define _CSMigrateTo(KEY, LAYER_IDENTIFIER, CLASS, SETTINGS_KEY) \
do { \
    id value;   \
    if (willBeMigratedData == nil) {\
        value = [[NSUserDefaults standardUserDefaults] objectForKey: KEY]; \
    } else { \
        value = [willBeMigratedData cs_valueForJSONKeyPath:KEY error: NULL]; \
    }\
    if (value != nil) {\
        NSString *key = [NSString stringWithFormat:@"%@.%@.%@", LAYER_IDENTIFIER, @#CLASS, SETTINGS_KEY]; \
        [migratingData cs_setValue:value forJSONKeyPath:key error:NULL]; \
        if (willBeMigratedData == nil) { \
            [[NSUserDefaults standardUserDefaults] removeObjectForKey: KEY]; \
        } \
    } \
    [migratedKeys addObject:KEY]; \
} while(0)


@interface CSMigrator : NSObject
+ (void)migratePlistPath:(NSString *)path migration:(NSArray *(^)(NSDictionary *data))migration completion:(void (^)(NSArray *migratedKeys))completion;
+ (void)migrateDictionary:(NSDictionary *)data  migration:(NSArray *(^)(NSDictionary *data))migration completion:(void (^)(NSArray *migratedKeys))completion;
@end