iCloud - How to save archive containing array of c

2019-04-10 04:20发布

问题:

I have developed a small app that stores locally in iOS through archiving an array of custom objects containing:

@property (nonatomic, copy) NSString    *name;
@property (nonatomic, copy) NSString    *dateCreated;
@property (nonatomic, copy) NSString    *desc;
@property (nonatomic, copy) NSString    *url;

I want to sync said archive using iCloud and I believe the recommended mechanism is through a UIDocument subclass. All UIDocument examples I found utlilized a single instance with 1 single NSString, so I am a little confused how to go about syncing a whole array of custom objects but utilizing UIDocument (like I do today locally through NSCoding).

Should I create an array of UIDocument objects containing the properties listed above, should I create an instance of UIDocument containing 1 instance of the data object described above and then create an array containing all the instances, or should 1 single UIDocument contain the complete array of custom objects ?

I have done some research but I am still confused. In the end I would need to sync just 1 file containing an array of said custom objects.

Thanks in advance for your help

What I have today is a custom class as described above with 4 strings called Snippet and in my Root view Controller I have an NSMutableArray called list where I add each new instance of that Snippet Class.

self.list = [[NSMutableArray alloc] init];
Snippet *newEntry = [[Snippet alloc] init];
[self.list addObject:newEntry];

Should I create an UI Document subclass that owns the array of custom objects ?

回答1:

The example in the docs does indeed show a UIDocument subclass that just has one string, but it returns a NSData from -contentsForType:error:. You can store as many objects as you like in an NSData using an NSKeyedArchiver. Read Serializing Objects to learn how to encode objects using NSKeyedArchiver (and keep reading to learn how to get them back!).

Using your properties as an example...

@interface MyDocument : UIDocument
{
}
@property (nonatomic, copy) NSString    *name;
@property (nonatomic, copy) NSString    *dateCreated;
@property (nonatomic, copy) NSString    *desc;
@property (nonatomic, copy) NSString    *url;
@end

@implementation MyDocument

//...

- (id)contentsForType:(NSString *)typeName error:(NSError **)outError
{
    NSMutableData *data = [NSMutableData data];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:name forKey:@"name"];
    [archiver encodeObject:dateCreated forKey:@"created"];
    [archiver encodeObject:desc forKey:@"desc"];
    [archiver encodeObject:url forKey:@"url"];
    [archiver finishEncoding];
    // release archiver if you're not using ARC
    return data;
}
@end;

WARNING: I haven't compiled the code above, so no guarantees. This should serve as an example to illustrate using an archiver to store multiple objects in a single data object which you can return as your document's content.