自定义plist文件中的变量

时间:2013-09-09 22:51:47

标签: ios objective-c variables plist

我知道可以通过预处理Info.plist文件将变量存储在默认的Info.plist文件中。我想知道是否可以使用自定义plist文件执行类似的操作。

我通过以下代码加载plist文件:

NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *customPlistPath = [path stringByAppendingPathComponent:@"custom.plist"];
NSDictionary *plistData = [NSDictionary dictionaryWithContentsOfFile:customPlistPath];

是否可以输入$ {PRODUCT_NAME}或$ {MY_OWN_VARIABLE_NAME}之类的值,并在我阅读之后将其置于自定义plist文件中?目前,当我将自定义plist文件读入NSDictionary

时,变量值不会被替换

1 个答案:

答案 0 :(得分:1)

Cocoa Touch框架中没有任何内置功能可以为您完成此任务。您必须编写自己的代码以在运行时处理值。我已经为自己的应用做了这个。我在实用程序类中使用了这两种方法。

+ (NSString *)processVariables:(NSString *)string {
    if (string.length == 0) {
        return string;
    }

    NSRange range = [string rangeOfString:@"${" options:NSLiteralSearch];
    if (range.location != NSNotFound) {
        NSMutableString *res = [string mutableCopy];
        do {
            NSRange close = [res rangeOfString:@"}" options:NSLiteralSearch];
            if (close.location == NSNotFound) {
                break; // Uh-oh - bad
            }

            NSRange rngVar = NSMakeRange(range.location, close.location - range.location + 1);
            NSString *var = [res substringWithRange:NSMakeRange(rngVar.location + 2, rngVar.length - 3)];
            NSString *val = [variables objectForKey:var];
            if (val) {
                [res replaceCharactersInRange:rngVar withString:val];
            } else {
                [res replaceCharactersInRange:rngVar withString:var];
            }

            range = [res rangeOfString:@"${" options:NSLiteralSearch];
        } while (range.location != NSNotFound);

        return res;
    } else {
        return string;
    }
}

+ (id)expandPlistVariables:(id)root {
    if ([root isKindOfClass:[NSArray class]]) {
        NSArray *array = (NSArray *)root;
        NSMutableArray *res = [[NSMutableArray alloc] initWithCapacity:array.count];
        for (id obj in array) {
            if ([obj isKindOfClass:[NSString class]]) {
                [res addObject:[self processVariables:(NSString *)obj]];
            } else {
                id newObj = [self expandPlistVariables:obj];
                [res addObject:newObj];
            }
        }

        return res;
    } else if ([root isKindOfClass:[NSDictionary class]]) {
        NSDictionary *dict = (NSDictionary *)root;
        NSMutableDictionary *res = [[NSMutableDictionary alloc] initWithCapacity:dict.count];
        for (NSString *key in [dict allKeys]) {
            id obj = dict[key];
            if ([obj isKindOfClass:[NSString class]]) {
                res[key] = [self processVariables:(NSString *)obj];
            } else {
                id newObj = [self expandPlistVariables:obj];
                res[key] = newObj;
            }
        }

        return res;
    } else {
        // oops
        return root;
    }
}

您将传入从plist加载的字典(或数组)并返回一个新的字典(或数组),其中包含变量引用的所有字符串值都已更新。

NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *customPlistPath = [path stringByAppendingPathComponent:@"custom.plist"];
NSDictionary *plistData = [NSDictionary dictionaryWithContentsOfFile:customPlistPath];
plistData = [UtilityClass expandPlistVariables:plistData];

在代码中,variables是包含变量值的NSDictionary。此词典中的键是plist中${}之间的值。例如:

variables = @{ @"PRODUCT_NAME" : @"MyProduct", @"MY_OWN_VARIABLE_NAME" : @"Some Value" };