Dzisiaj postanowiłem jak napisać jak obsłużyć pliki pisząc aplikację na telefon iPhone. Zapisywanie plików może być przydatne w wielu sytuacjach np. jako cache, zapisanie stanu aplikacji lub wyniki w grach. Pokaże zapisywanie/odczytawanie plików w dokumentach oraz wczytywanie plików znajdujących się w projekcie.

Zapis plików

Na początku utworzyłem sobie metodę, w którą pobieram ścieżkę pliku

- (NSString *)getPathToFile
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                      NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    return [NSString stringWithFormat: @"%@/file.xml", documentsDirectory];
}

Nie zapomnij utworzyć deklaracji metody w pliku .h. Typ NSDocumentDirectory określa katalog w jakim chcemy zapisać plik i tak mamy do dyspozycji następujące typy:

Dokładne opisy w dokumentacji linki w liście. Teraz przejdźmy do zapisu pliku z wykorzystaniem powyższej metody:

- (BOOL)writeToFile
{
    NSArray *data = [NSArray arrayWithObject:@"some object"];
   return [data writeToFile:[self getPathToFile] atomically:YES];
}

metoda writeToFile:atomically zwraca wartość BOOL mówiąca czy się udało zapisać do pliku. Jeżeli atomically jest ustawione na tak dane są zapisywane do pliku pomocniczego, a następnie plik ten ma zmienianą nazwę na właściwą. Gwarantuje to zapis nawet jeśli coś stanie się z systemem.
Powyższy sposób jest najprostszym na zapisanie danych jeżeli chcemy zapisać tablicę (NSArray) lub słownik (NSDictionary). Jeżeli chcemy tak postąpić z obiektem NSDate. Musimy zamienić dane do formatu NSPropertyListBinaryFormat_v1_0:

- (BOOL)writeToFile
{
    NSString *error;
    NSData *pData = [NSPropertyListSerialization dataFromPropertyList:plist
                             format:NSPropertyListBinaryFormat_v1_0
                             errorDescription:&error];
    if (!pData) {
        NSLog(@"%@", error);
        return NO;
    }
    return ([self writeApplicationData:pData toFile:[self getPathToFile]]);
}

Trzeba przyznać, że obsługa plików jest zrobiona dość zgrabnie w Objective-C. Nie martwimy się o otwieranie zamykanie pliku itp. sprawy. Pliki zapisywane są w postaci xmla opisującego strukturę danych, którą zapisujemy.

Odczyt plików

- (NSArray *)readFromFile
{
   NSData *plistData;
   NSString *error;
   NSArray *data;
   NSPropertyListFormat format = NSPropertyListXMLFormat_v1_0;

   plistData = [NSData dataWithContentsOfFile:[self getPathToFile]];
   data = [NSPropertyListSerialization propertyListFromData:plistData
                       mutabilityOption:NSPropertyListImmutable
                       format:&format errorDescription:&error];
   if(!data)
   {
          /* działanie w przypadku nie wczytania pliku 
           * Ja zwracam akurat pustą tablicę
           */
          [error release];
          return [[NSArray alloc] init];
    }
    /* zwrócenie danych */
    return dane;
}

Odczytywanie plików dostępnych w projekcie

Jedyne co musimy zmienić w odczytywanie pliku z katalogu projektu to metodę zwracającą nazwę pliku:

- (NSString *)getPathToFile
{
    NSString *filePath = [[NSBundle mainBundle] resourcePath];
    return [NSString stringWithFormat: @"%@/file.xml", filePath];
}

To wszystko jeśli chodzi o podstawy obsługi plików w Objective-C. Korzystajcie z plików w ułatwiania życia użytkownikom.
Jeżeli piszesz coś w Objective-C i nie możesz sobie z czymś poradzić napisz w komentarzu. Może ja albo moi koledzy się spotkaliśmy się już z tym i pomożemy Ci :)