Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Long delay with NSFileCoordinator coordinateWritingItemAtURL

I'm setting up NSFileCoordinator and NSFilePresenter in my app so I can do file IO from my AppleWatch app safely. There are some places in my code where I write to a file a couple of times in quick succession. This is a problem in and of itself and I'm working to correct it, but I'm noticing some weird behavior in the process.

I wrap my writes like this:

//In a class that implements NSFilePresenter:
NSFileCoordinator *coord = [[NSFileCoordinator alloc]initWithFilePresenter:self];
[coord coordinateWritingItemAtURL:self.presentedItemUrl options:0 error:nil byAccessor:^(NSURL *url)
{
  //do my writing here using CFWriteStreamRef or NSOutputStream
}];

On the first write, the write block happens within 1 ms. But after that, there's about a 0.5 second delay between calling coordinateWritingItemAtURL and the write block being executed.

Is this expected behavior?

Some of the documentation for NSFileCoordinator and NSFilePresenter says to use prepareForReadingItemsAtURLs:writingItemsAtURLs:options:error:byAccessor: for batch operations, but it seems weird to get such a long delay when I don't batch.

Update: This happens with reading too.

Update 2: Here is an example project reproducing the problem.

Update 3: Using this API for coordination between an app and its extension is apparently a bad idea. But the question still stands.

like image 454
Tom Hamming Avatar asked Apr 16 '15 15:04

Tom Hamming


2 Answers

Referring to File System Programming Guide , you can read following:

you might want to avoid incorporating changes directly from your file presenter method. Instead, dispatch a block asynchronously to a dispatch queue and process the changes at a later time. This lets you process the changes at your app’s convenience without causing unnecessary delays to the file coordinator that initiated the change. Of course, when saving or relinquishing control of a file (such as in the relinquishPresentedItemToReader:, relinquishPresentedItemToWriter:, or savePresentedItemChangesWithCompletionHandler: methods) you should perform all necessary actions immediately and not defer them.

I think this is your case where you are defering actions.

Possible Solution:

Please read this well , to properly handle multiple successive writing operations , the relinquishPresentedItemToWriter , can do the job , same will work with reading file , relinquishPresentedItemToReader , supposing that multiple different objects are trying to read and write the same file.

P.S :

I dont know what your app does exactly , but i hope you have read this :

If you are implementing a document-based app, you do not need to incorporate file presenter semantics into your NSDocument subclasses. The NSDocument class already conforms to the NSFilePresenter protocol and implements the appropriate methods. Thus, all of your documents automatically register themselves as presenters of their corresponding file and do things like save changes and track changes to the document.

like image 86
ProllyGeek Avatar answered Nov 17 '22 12:11

ProllyGeek


Is it possible to use options NSFileCoordinatorReadingImmediatelyAvailableMetadataOnly for reading and NSFileCoordinatorWritingContentIndependentMetadataOnly for writing in some cases? Looks like this iOS8 options can help you.

like image 44
k06a Avatar answered Nov 17 '22 11:11

k06a