I have a basic iOS app that shows a list of documents. I'm trying to delete a document, but noticed that the code below fails with "No such file or directory" if the document has not yet been downloaded from iCloud to the device.
Documents can be quite large (40MB) and I'd like to avoid downloading the document only to delete it (this takes time and bandwidth out of the user's data plan). Is this possible at all?
[[[NSFileCoordinator alloc] initWithFilePresenter:nil]
coordinateWritingItemAtURL:documentURL
options:NSFileCoordinatorWritingForDeleting
writingItemAtURL:previewURL
options:NSFileCoordinatorWritingForDeleting
error:&error
byAccessor:^(NSURL *newDocumentURL, NSURL *newPreviewURL){
// Fails with "No such file" error if not yet downloaded from iCloud:
[[NSFileManager defaultManager] removeItemAtURL:newDocumentURL error:&error];
[[NSFileManager defaultManager] removeItemAtURL:newPreviewURL error:&error];
}];
The full error:
Error Domain=NSCocoaErrorDomain Code=4 "The operation couldn’t be completed.
(Cocoa error 4.)" UserInfo=0x14e82930 {NSUnderlyingError=0x14e69220
"The operation couldn’t be completed. No such file or directory",
If you just need to delete a file, use the other NSFileCoordinator coordinateWritingItemAtURL ( the one with a single newURL parameter in the accessor block ).
If you need to batch delete, then create an array of NSFileAccessIntent and use NSFileCoordinator's coordinateAccessWithIntents.
Example:
- ( void )deleteItemsAtURLs: ( NSArray * )urls queue: ( NSOperationQueue * )queue
{
//assuming urls is an array of urls to be deleted
NSFileCoordinator * coordinator;
NSMutableArray * writingIntents;
NSURL * url;
writingIntents = [ NSMutableArray arrayWithCapacity: urls.count ];
for( url in urls )
{
[ writingIntents addObject: [ NSFileAccessIntent writingIntentWithURL: url options: NSFileCoordinatorWritingForDeleting ] ];
}
coordinator = [ [ NSFileCoordinator alloc ] initWithFilePresenter: nil ];
[ coordinator coordinateAccessWithIntents: writingIntents
queue: queue
byAccessor: ^( NSError * error )
{
if( error )
{
//handle
return;
}
NSFileAccessIntent * intent;
error = nil;
for( intent in writingIntents )
{
[ [ NSFileManager defaultManager ] removeItemAtURL: intent.URL error: &error ];
if( error )
{
//handle
}
}
}];
}