将CLLocation保存到plist

时间:2012-04-19 12:43:44

标签: objective-c ios plist

我努力将多个位置保存到plist文件中供以后使用, 经过一段谷歌搜索后,我发现一个CLLocation本身的数组无法保存, 所以我想知道如何做到这一点。

我正在考虑几个课程,以及#34;序列化" /" deserilize"将单个CLLocation对象放入NSDictionary,然后将这些NSDictionaries的数组存储到plist文件中,但我想知道是否有更好/更智能/可靠的方法来实现它。

提前感谢。

编辑:

这是我用来保存plist中的数据的函数(c_propertyName从答案中获取代码)

    - (void) addLocation {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"/Locations.plist"];

        NSArray *keys = [curLocation c_propertyNames];
        NSDictionary *dict = [curLocation dictionaryWithValuesForKeys:keys];

        [dict writeToFile: path atomically:YES];
    }

编辑2 - 解决方案:

好的,我已经全力以赴了。在下面,我已经发布了一个针对我自己的问题的两个选项解决方案。

3 个答案:

答案 0 :(得分:3)

KVC很容易。

这是获取属性名称的NSObject类别的方法(需要<objc/runtime.h>

- (NSArray *)c_propertyNames {
    Class class = [self class];
    u_int count = 0;

    objc_property_t *properties = class_copyPropertyList(class, &count);
    if (count <= 0) {
        return nil;
    }
    NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, count)];

    NSMutableSet *retVal = [NSMutableSet setWithCapacity:count];
    [set enumerateIndexesWithOptions:NSEnumerationConcurrent 
                          usingBlock:^(NSUInteger idx, BOOL *stop) {
                              const char *propName = property_getName(properties[idx]); 
                              NSString *name = [NSString stringWithUTF8String:propName];
                              [retVal addObject:name];
                          }];
    return [retVal allObjects];
}

然后像这样使用它:

NSArray *keys = [yourLocation c_propertyNames];
NSDictionary *dict = [yourLocation dictionaryWithValuesForKeys:keys];

然后保存该字典。

答案 1 :(得分:3)

我喜欢solution 2,但是如果所有人都想直接写入文件,那么序列化会更简单。

[NSKeyedArchiver archiveRootObject:arrayOfLocations toFile:path];

答案 2 :(得分:0)

经过几个小时的搜索,我发现了整个场景。 在这里你有几个解决方案;第一个是更“脏”,因为它是我想出的第一个,而第二个是更优雅。无论如何,我会离开,因为也许他们都可以派上用场。

S O L U T I O N - 1

感谢mit3z的帮助,我可以把各个部分组合起来找出解决方案。

正如他指出的那样,你可以将这个方法实现到NSObject的一个类别中:

 - (NSArray *)c_propertyNames;

(看看他对这部分代码的回应以及有关它的更多细节)

这让我有自由做这件事:

- (void) addLocation {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"/Locations.plist"];

    NSArray *keys = [curLocation c_propertyNames]; // retrieve all the keys for this obj
    NSDictionary *values = [self.curLocation dictionaryWithValuesForKeys:keys];
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    for(NSString *key in keys) {
        NSString *aaa = [NSString stringWithFormat:@"%@", (NSString *)[values valueForKey:key]];
        [dict setValue:aaa forKey:key];
    }

    [dict writeToFile:path atomically:YES];
}

需要使用superdumb for循环将NSDictionary中的所有数据转换为NSStrings,以便它们可以毫无困难地写入plist文件,如果你只是制作字典然后你试图立即保存它,你想要没成功。

通过这种方式,我可以将所有CLLocation obj“序列化”到一个字典中,然后写入一个plist文件。

S O L U T I O N - 2

我提出了一种非常简单(也更优雅)的方法:使用 NSCoding 。  由于(我意识到) CLLocation 数据类型符合 NSCoding 的事实,您可以通过 NSKeyedArchiver 调用数据存档器以获取blob描述你的数组,然后将它存储到plist,就像那样:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"/Locations.plist"];
NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile: path];

[data setValue:[NSKeyedArchiver archivedDataWithRootObject:arrayOfLocations] forKey:@"LocationList"];
[data writeToFile:path atomically:YES];
[data release];

并且瞧'就那么简单! :)

基于相同的原则,您可以通过 NSKeyUnarchiver 轻松获取数据:

self.arrayOfLocations = [[NSMutableArray alloc] initWithArray:[NSKeyedUnarchiver unarchiveObjectWithData: (NSData *)[dict objectForKey:@"LocationList"]]];