I'm having a lot of trouble deciphering Apple's documentation around UIManagedDocument
, specifically the following methods:
- (id)additionalContentForURL:(NSURL *)absoluteURL error:(NSError **)error
- (BOOL)readAdditionalContentFromURL:(NSURL *)absoluteURL error:(NSError **)error
- (BOOL)writeAdditionalContent:(id)content toURL:(NSURL *)absoluteURL originalContentsURL:(NSURL *)absoluteOriginalContentsURL error:(NSError **)error
Has anyone successfully managed to save additional content into the "addition content" directory inside their UIManagedDocument packages? I'm looking to save straight images (PNGs, JPEGs, etc) and videos (m4v, etc) into this directory using UUIDs as the filenames (with the correct file extension), and storing references to these individual files as NSString
file paths within my persistent store.
Credit goes to Apple DTS for helping me understand this class. I'm sharing some of the example they helped me with here (modified slightly).
OK, so basically it works like this: subclass UIManagedDocument
, and implement the following methods (where the extraInfo
property is just an NSDictionary implemented on our subclass):
- (BOOL)readAdditionalContentFromURL:(NSURL *)absoluteURL error:(NSError **)error
{
NSURL *myURL = [absoluteURL URLByAppendingPathComponent:@"AdditionalInformation.plist"];
self.extraInfo = [NSDictionary dictionaryWithContentsOfURL:myURL];
return YES;
}
- (id)additionalContentForURL:(NSURL *)absoluteURL error:(NSError **)error
{
if (!self.extraInfo) {
return [NSDictionary dictionaryWithObjectsAndKeys: @"Picard", @"Captain", [[NSDate date] description], @"RightNow", nil];
} else {
NSMutableDictionary *updatedFriendInfo = [self.extraInfo mutableCopy];
[updatedFriendInfo setObject:[[NSDate date] description] forKey:@"RightNow"];
[updatedFriendInfo setObject:@"YES" forKey:@"Updated"];
return updatedFriendInfo;
}
}
- (BOOL)writeAdditionalContent:(id)content toURL:(NSURL *)absoluteURL originalContentsURL:(NSURL *)absoluteOriginalContentsURL error:(NSError **)error
{
if (content) {
NSURL *myURL = [absoluteURL URLByAppendingPathComponent:@"AdditionalInformation.plist"];
[(NSDictionary *)content writeToURL:myURL atomically:NO];
}
return YES;
}
UIManagedDocument
will call these methods when it needs to, automatically saving whatever you need to save to the document package inside an AdditionalContent
directory.
If you need to force a save, simply call the following on your UIManagedDocument
instance:
[self updateChangeCount:UIDocumentChangeDone];
At present, I'm not using this for images and videos — but the example should give you enough to go off.
The documentation for -additionalContentForURL:error: indicates that returning a nil supposed to signal an error.
A return value of nil indicates an error condition. To avoid generating
an exception, you must return a value from this method. If it is not always
the case that there will be additional content, you should return a sentinel value (for example, an NSNull instance) that you check for in
writeAdditionalContent:toURL:originalContentsURL:error:.
I override -writeContents:andAttributes:safelyToURL:forSaveOperation:error:
for another purpose (doing some stuff on first save of a new document), and calling super invokes the NSException gods because contents
value is nil, not an NSDictionary as seemingly expected by UIManagedDocument. Hmm.
The more you know...
P.S. I guess it depends on the time of day with -writeContents:andAttributes:... It once threw an exception complaining about expecting an NSDictionary, but later threw an exception complaining that I didn't pass it an NSData. My eyebrow could not be raised in a more Spock-like fashion than it is right now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With