Een plist-bestand delen met iCloud

Ik heb een eenvoudige relativley-app die gegevens aanhoudt voor een plist-bestand in de documentenmap. De gegevens worden bij het opstarten in een UITableView geladen. De gebruiker kan vervolgens records bewerken en verwijderen en alle wijzigingen worden terug opgeslagen in het plist-bestand.

Nu wil ik deze gegevens (het plist-bestand) delen op verschillende apparaten met iCloud. Ik heb de documentatie bekeken en mijn begrip is dat ik een UIDdocument moet maken om het plist-bestand te "beheren".

Ik heb verschillende iCloud-tutorials bekeken, maar ze slaan allemaal een eenvoudige string op in een eigenschap in de UIDocument-klasse, niet een volledig bestand (zoals een plist).

Hoe deel ik mijn plist-bestand (of een ander bestand, wat dat betreft) met iCloud met het UIDocument-object?

Zou ik de inhoud van het plist-bestand naar NSData converteren en dat opslaan in een eigenschap in het UID-document? Moet ik in plaats daarvan NsFileWrapper gebruiken?

Ik heb moeite met het omwikkelen van het UIDocument/iCloud-arrangement. Ik maak dit waarschijnlijk gecompliceerder dan het in werkelijkheid is.

7
Heb je hier een antwoord voor gevonden? Ik kijk ernaar hetzelfde te doen en mijn app lijkt erg op de jouwe. Laat het me weten als je een goede tutorial hebt gevonden.
toegevoegd de auteur Jackson, de bron
Ik probeer dit ook te bereiken. Ik heb de tutorial aangepast met de NSString, maar ik krijg niet het tweede apparaat om de gegevens te zien.
toegevoegd de auteur zambono, de bron
idem dito. +1 naar poster
toegevoegd de auteur autodidakto, de bron

2 antwoord

Ik weet niet zeker of iemand daar nog steeds een oplossing voor nodig heeft, maar ik heb een leuke manier gevonden om dit te laten werken.

Omdat UIDocument alleen gegevens als NSData of NSFilewrapper accepteert, heb ik eerst een categorie gemaakt voor de NSDictionary-klasse die een NSDictionary uit NSData retourneert. Dit zijn de twee bestanden voor de Categorie:

NSDictionary + DictFromData.h:

#import 

@interface NSDictionary (DictFromData)
+ (id)dictionaryWithData:(NSData *)data;
- (id)initWithData:(NSData *)data;
@end

en de NSDictionary + DictFromData.m

#import "NSDictionary+DictFromData.h"
@implementation NSDictionary (DictFromData)

+ (id)dictionaryWithData:(NSData *)data {
    return [[[NSDictionary alloc] initWithData:data] autorelease];
}

- (id)initWithData:(NSData *)data {
    NSString *tmp = nil;

    self = (NSDictionary *)[NSPropertyListSerialization
                            propertyListFromData:data
                            mutabilityOption:NSPropertyListImmutable
                            format:NULL
                            errorDescription:&tmp];

    NSAssert1(tmp == nil,@"Error in plist: %@",tmp);
    return [self retain];
}
@end

( bron )

Als u nu deze categorie in uw UIDocument-subklasse importeert, kunt u eenvoudig uw Plist-bestand in uw iCloud-container laden en opslaan.

Om Plist vanuit iCloud te laden, voeg je dit toe aan je UIDocument subklasse (de inhoud van de eigenschap is een NSDictionary):

- (BOOL)loadFromContents:(id)contents
                  ofType:(NSString *)
        typeName error:(NSError **)outError {

    if ([contents length] > 0){
        self.contents = [NSDictionary dictionaryWithData:contents];
    } else {
        self.contents = nil;
    }

   //call some Methods to handle the incoming NSDictionary 
   //maybe overwrite the old Plist file with the new NSDictionary

    return YES;
}

Voor het opslaan van uw gegevens terug naar de iCloud voegt u dit toe:

- (id)contentsForType:(NSString *)typeName error:(NSError **)outError {
    NSData * plistData = [[[NSData alloc]initWithContentsOfFile:YOUR_PLIST_FILE]autorelease];
    return plistData;
}

Als je nu belt:

[myUIDocument updateChangeCount:UIDocumentChangeDone];

YOUR_PLIST_FILE wordt gesynchroniseerd. Vergeet niet dat het ongeveer 10-15 seconden duurt voordat uw iCloud-container is bijgewerkt.

7
toegevoegd

Als u een plist met UIDocument wilt gebruiken, kunt u UIDocument subclassificeren en de volgende 2 methoden overschrijven met self.myDictionary (uw plist) die als een NSMutableDictionary is gedeclareerd.

- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError
{    
    if ([contents length] > 0) 
    {
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:(NSData *)contents];
        NSMutableDictionary *dataDictionary = [unarchiver decodeObjectForKey:@"data"];

        self.myDictionary = dataDictionary;
        [unarchiver finishDecoding];
        [unarchiver release];
    } 
    else 
    {
        self.myDictionary =  [NSMutableDictionary dictionary];
    }

    return YES;    
}

- (id)contentsForType:(NSString *)typeName error:(NSError **)outError 
{
    NSMutableData *data = [[[NSMutableData alloc] init] autorelease];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    if( !self.myDictionary )
    {
        self.myDictionary = [NSMutableDictionary dictionary];
    }
    [archiver encodeObject:self.myDictionary forKey:@"data"];

    [archiver finishEncoding];
    [archiver release];
    return data;
}
1
toegevoegd
Dit maakt geen woordenboek aan, maar het creëert een archiefplatt maar is voldoende dichtbij. Gebruik NSPropertyListSerialization om een ​​echte plist te maken en u kunt xml- of binaire uitvoer kiezen.
toegevoegd de auteur malhal, de bron
Ook archive plists zijn niet compatibel tussen Macs en iOS.
toegevoegd de auteur malhal, de bron