Запись NSMutableArray в каталог моих документов не удалась - PullRequest
0 голосов
/ 28 декабря 2010

Я пытаюсь кэшировать веб-запрос. По сути, у меня есть приложение, которое использует список друзей пользователя Facebook, но я не хочу получать его каждый раз, когда они входят в систему. Может обновляться один раз в месяц. Кэширование списка друзей в списке в каталоге документов, кажется, имеет смысл для этой функции. Я делаю это следующим образом:

- (void)writeToDisk {
    NSLog(@"writing cache to disk, where cache = %@", cache);
    BOOL res = [cache writeToFile:[FriendCache persistentPath] atomically:YES];
    NSLog(@"reading cache from disk immediately after writing, res = %d", res);
    NSMutableArray *temp = [[NSMutableArray alloc] initWithContentsOfFile:[FriendCache persistentPath]];
    NSLog(@"cache read in = %@", temp);
}

+ (NSString *)persistentPath {
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    return [documentsDirectory stringByAppendingPathComponent:@"FriendCache.plist"];
}

Это члены сингтона FriendCache, который я использую, который в основном обертывает NSMutableArray. Я проверил, что метод peristentPath возвращает правильный путь. Как вы можете видеть в методе writeToDisk, я проверяю, есть ли данные в кеше, и затем печатаю результат записи и проверяю, можно ли считать какие-либо данные обратно. Данные никогда не считываются обратно, потому что результат запись в файл равна 0.

Вывод из кэша распечатывается очень долго, но вот сокращенная версия:

2010-12-28 13:35:23.006 AppName[51607:207] writing cache to disk, where cache = (
        {
        birthday = "<null>";
        name = "Some Name1";
        pic = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs1324.snc4/7846385648654.jpg";
        "pic_big" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs442.snc4/784365789465746.jpg";
        "pic_square" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs1324.snc4/7846357896547.jpg";
        sex = female;
        status = "<null>";
        uid = 892374897165;
    },
        {
        birthday = "<null>";
        name = "Some Name2";
        pic = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs625.ash1/54636536547_s.jpg";
        "pic_big" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs170.ash2/65465656365666_n.jpg";
        "pic_square" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs625.ash1/654635656547_q.jpg";
        sex = female;
        status = "<null>";
        uid = 7658436;
    },

...

Одна вещь, которую я проверял, при использовании writeToFile, я должен убедиться, что объект, который я пишу, имеет допустимые объекты plist. Я проверил это, и вот как я создаю объект кеша:

- (void)request:(FBRequest*)request didLoad:(id)result{
    NSMutableArray *friendsInfo = [[[NSMutableArray alloc] init] autorelease];

    for (NSDictionary *info in result) {
        NSString *friend_id = [NSString stringWithString:[[info objectForKey:@"uid"] stringValue]];
        NSString *friend_name = nil;
        NSString *friend_sex = nil;
        NSString *friend_relationship_status = nil;
        NSString *friend_current_location = nil;
        if ([info objectForKey:@"name"] != [NSNull null]) {
            friend_name = [NSString stringWithString:[info objectForKey:@"name"]];
        }
        if ([info objectForKey:@"relationship_status"] != [NSNull null]) {
            friend_relationship_status = [NSString stringWithString:[info objectForKey:@"relationship_status"]];
        }
        if ([info objectForKey:@"sex"] != [NSNull null]) {
            friend_sex = [NSString stringWithString:[info objectForKey:@"sex"]];
        }
        if ([info objectForKey:@"current_location"] != [NSNull null]) {
            friend_current_location = [[info objectForKey:@"current_location"] objectForKey:@"name"];
        }
        NSString *friend_pic_square = [info objectForKey:@"pic_square"];
        NSString *friend_status = [info objectForKey:@"status"];
        NSString *friend_pic = [info objectForKey:@"pic"];
        NSString *friend_pic_big = [info objectForKey:@"pic_big"];
        NSString *friend_birthday = [info objectForKey:@"birthday"];
        NSDictionary *friend_info = [NSDictionary dictionaryWithObjectsAndKeys:
                                            friend_id,@"uid",
                                            friend_name, @"name", 
                                            friend_pic_square, @"pic_square", 
                                            friend_status, @"status",
                                            friend_sex, @"sex",
                                            friend_pic, @"pic",
                                            friend_pic_big, @"pic_big",
                                            friend_birthday, @"birthday",
                                            friend_relationship_status, @"relationship_status",
                                            friend_current_location, @"current_location",
                                            nil];

        // If the friend qualifies as a single of your gender, add to the friend cache
        if ( [AppHelpers friendQualifies:friend_info] == YES) {
            [[FriendCache sharedInstance] push:friend_info];
        }
    }
    [[FriendCache sharedInstance] writeToDisk];

}

Мой метод push просто оборачивает push NSMutableArray:

- (void)push:(id)o {
    [cache addObject:o];
}

Можете ли вы вспомнить причину, по которой запись не удалась?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 28 декабря 2010

Итак, как мы уже указывали, это из-за использования NSNull объектов.

Лучший способ избежать этого - создать объект Friend со всеми необходимыми свойствами. Тогда вы можете легко установить nil значения, что невозможно с NSDictionary объектами (ну, вам придется удалить ключ, что не очень хорошая практика).

Затем, реализуя протокол NSCoding, вы можете легко архивировать (сериализовать) свой пользовательский объект.

Это намного лучший способ обработки ваших данных, и в будущем он станет НАМНОГО проще. Вы сможете вызывать сообщения на Friend объектах, что невозможно с NSDictionary.

1 голос
/ 28 декабря 2010

Используйте API с поддержкой NSError для NSPropertyListSerialization для получения данных и API записи с NSData NSError, чтобы вы получили значимую ошибку, помогающую понять, в чем может быть ваша проблема.

...