Re: Unwanted presentedItemDidMoveToURL: for old file after using setFileURL: to specify a new file

2013-09-18 Thread Brian Clark
A follow-up as a result of more testing.

It's not actually necessary to do the read via 
-revertToContentsOfURL:ofType:error: in a File Access block to solve the 
problem I had, though I'm sure it's best to do so (and that's what I now do).

Similarly moving the file to the Trash or deleting it should probably also be 
done in a File Access block, and that's what I now do to.

But there's an exception to this rule. In my app, if the displayed file is 
marked as to be trashed, it's moved to the Trash when the window is closed in 
the document's -close method (before calling [super close] ). But this results 
in a hang if it's done inside a [self performSynchronousFileAccessUsingBlock:^{ 
... }]; block. So in this case a File Access block apparently can't be used.

On Sep 16, 2013, at 12:24 PM, Kevin Perry kpe...@apple.com wrote:

 But, I suspect the problem here is that you're not using File Coordination 
 when reading in the contents of the new file. By not doing that, you're not 
 giving File Coordination the hint that it needs to check back with your 
 NSFilePresenter (the NSDocument) for its presentedItemURL. When you read in 
 the contents of the new file you should:
 
 1) Start a File Access with -performSynchronousFileAccessUsingBlock: or 
 -performAsynchronousFileAccessUsingBlock
 2) Create an NSFileCoordinator instance with the NSDocument as the 
 NSFilePresenter passed in the initializer.
 3) Using that NSFileCoordinator, take a coordinated read of the target file
 4) Inside the coordinated read: read the contents of the new file 
 (-revertToContentsOfURL:ofType:error: is probably the most correct here, as 
 it will update -fileURL, -fileModificationDate, -fileType, change counts, and 
 other internal state as necessary)

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Unwanted presentedItemDidMoveToURL: for old file after using setFileURL: to specify a new file

2013-09-18 Thread Kevin Perry

On Sep 18, 2013, at 6:53 AM, Brian Clark ba-cl...@comcast.net wrote:

 A follow-up as a result of more testing.
 
 It's not actually necessary to do the read via 
 -revertToContentsOfURL:ofType:error: in a File Access block to solve the 
 problem I had, though I'm sure it's best to do so (and that's what I now do).
 
 Similarly moving the file to the Trash or deleting it should probably also be 
 done in a File Access block, and that's what I now do to.
 
 But there's an exception to this rule. In my app, if the displayed file is 
 marked as to be trashed, it's moved to the Trash when the window is closed in 
 the document's -close method (before calling [super close] ). But this 
 results in a hang if it's done inside a [self 
 performSynchronousFileAccessUsingBlock:^{ ... }]; block. So in this case a 
 File Access block apparently can't be used.

FYI: You can get help discovering the cause of hangs involving 
performSynchronousFileAccessUsingBlock (and 
performActivityWithSynchronousWaiting:usingBlock:) by doing 'po 
_NSDocumentSerializationInfo()' in the debugger.

 
 On Sep 16, 2013, at 12:24 PM, Kevin Perry kpe...@apple.com wrote:
 
 But, I suspect the problem here is that you're not using File Coordination 
 when reading in the contents of the new file. By not doing that, you're not 
 giving File Coordination the hint that it needs to check back with your 
 NSFilePresenter (the NSDocument) for its presentedItemURL. When you read in 
 the contents of the new file you should:
 
 1) Start a File Access with -performSynchronousFileAccessUsingBlock: or 
 -performAsynchronousFileAccessUsingBlock
 2) Create an NSFileCoordinator instance with the NSDocument as the 
 NSFilePresenter passed in the initializer.
 3) Using that NSFileCoordinator, take a coordinated read of the target file
 4) Inside the coordinated read: read the contents of the new file 
 (-revertToContentsOfURL:ofType:error: is probably the most correct here, as 
 it will update -fileURL, -fileModificationDate, -fileType, change counts, 
 and other internal state as necessary)
 
 ___
 
 Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
 
 Please do not post admin requests or moderator comments to the list.
 Contact the moderators at cocoa-dev-admins(at)lists.apple.com
 
 Help/Unsubscribe/Update your Subscription:
 https://lists.apple.com/mailman/options/cocoa-dev/kperry%40apple.com
 
 This email sent to kpe...@apple.com


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Unwanted presentedItemDidMoveToURL: for old file after using setFileURL: to specify a new file

2013-09-16 Thread Mike Abdullah

On 14 Sep 2013, at 21:14, Brian Clark ba-cl...@comcast.net wrote:

 I'm hoping someone can suggest the correct way to deal with the following 
 problem.
 
 For an image viewing app i display a file in the usual way in an NSDocument. 
 setFileURL: is properly called by NSDocument's 
 _initWithContentsOfURL:ofType:error:.
 
 I now want to display the next file in the folder, and move the old file to 
 the Trash. To do this I do the necessary file reading tasks and call 
 setFileURL: with the new file URL. I then move the old file to the trash 
 (using NSFileManager 's trashItemAtURL:resultingItemURL:error: but using 
 different methods gives the same result.)

What are the necessary file reading tasks? Rather than call -setFileURL: 
yourself, have you tried calling -revertToContentsOfURL:ofType:error: instead? 
The top of the class documentation briefly notes that it should always be used 
for re-reading documents.
 
 Prior to 10.7 this worked fine and gave the desired result. Under 10.8, 
 shortly after I load the new file and call setFileURL: with the new file URL 
 as described above, I see a presentedItemDidMoveToURL: call with the old file 
 URL. From that point on, the document has the wrong URL associated with it.
 
 #00x000100014cf0 in -[ImageDoc setFileURL:] at 
 /Volumes/Data/Documents/Projects/Ptah/ptah src 3.1.0/Source/ImageDoc.m:3669
 #10x7fff84763b6f in __block_global_243 ()
 #20x7fff842fa869 in -[NSDocument continueFileAccessUsingBlock:] ()
 #30x7fff842fa432 in -[NSDocument 
 _performFileAccessOnMainThread:usingBlock:] ()
 #40x7fff842ff0d7 in -[NSDocument 
 performAsynchronousFileAccessUsingBlock:] ()
 #50x7fff84763b3d in __40-[NSDocument 
 presentedItemDidMoveToURL:]_block_invoke_0 ()
 #60x7fff832789cf in -[NSBlockOperation main] ()
 #70x7fff8324e926 in -[__NSOperationInternal start] ()
 #80x7fff832560f1 in __block_global_6 ()
 #90x7fff8750bf01 in _dispatch_call_block_and_release ()
 #10   0x7fff875080b6 in _dispatch_client_callout ()
 #11   0x7fff8750d0c8 in _dispatch_main_queue_callback_4CF ()
 #12   0x7fff8c4b4b4c in __CFRunLoopRun ()
 #13   0x7fff8c4b40e2 in CFRunLoopRunSpecific ()
 #14   0x7fff8b9e0eb4 in RunCurrentEventLoopInMode ()
 #15   0x7fff8b9e0c52 in ReceiveNextEventCommon ()
 #16   0x7fff8b9e0ae3 in BlockUntilNextEventMatchingListInMode ()
 #17   0x7fff8442a533 in _DPSNextEvent ()
 #18   0x7fff84429df2 in -[NSApplication 
 nextEventMatchingMask:untilDate:inMode:dequeue:] ()
 #19   0x7fff844211a3 in -[NSApplication run] ()
 #20   0x7fff843c5bd6 in NSApplicationMain ()
 #21   0x000100063f79 in main at 
 /Volumes/Data/Documents/Projects/Ptah/ptah src 3.1.0/Source/App.m:136
 #22   0x000120e4 in start ()
 
 What is the proper way to prevent this behavior? Obviously simply calling 
 setFileURL: with the new file URL does not fully establish the the document 
 is now associated only with the new file, and that the old file should be 
 forgotten and not associated in any way with the document. I'm not explicitly 
 using NSFileCoordinator or NSFilePresenter. This is a non-sandboxed app.
 ___
 
 Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
 
 Please do not post admin requests or moderator comments to the list.
 Contact the moderators at cocoa-dev-admins(at)lists.apple.com
 
 Help/Unsubscribe/Update your Subscription:
 https://lists.apple.com/mailman/options/cocoa-dev/mabdullah%40karelia.com
 
 This email sent to mabdul...@karelia.com


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Unwanted presentedItemDidMoveToURL: for old file after using setFileURL: to specify a new file

2013-09-16 Thread Brian Clark

On Sep 16, 2013, at 4:38 AM, Mike Abdullah mabdul...@karelia.com wrote:

 
 On 14 Sep 2013, at 21:14, Brian Clark ba-cl...@comcast.net wrote:
 
 I'm hoping someone can suggest the correct way to deal with the following 
 problem.
 
 For an image viewing app i display a file in the usual way in an NSDocument. 
 setFileURL: is properly called by NSDocument's 
 _initWithContentsOfURL:ofType:error:.
 
 I now want to display the next file in the folder, and move the old file to 
 the Trash. To do this I do the necessary file reading tasks and call 
 setFileURL: with the new file URL. I then move the old file to the trash 
 (using NSFileManager 's trashItemAtURL:resultingItemURL:error: but using 
 different methods gives the same result.)
 
 What are the necessary file reading tasks? Rather than call -setFileURL: 
 yourself, have you tried calling -revertToContentsOfURL:ofType:error: 
 instead? The top of the class documentation briefly notes that it should 
 always be used for re-reading documents.

The necessary tasks are readFromURL:ofType:error: and the other chores 
associated with setting up the document state for the different image file.

Using -revertToContentsOfURL:ofType:error: instead does not work. After doing 
this NSDocument still seems to treat the old URL as the file's document, and I 
still get presentedItemDidMoveToURL: for the old file URL when it is moved to 
the Trash AFTER I-ve called revertToContentsOfURL:ofType:error:. While 
revertToContentsOfURL:ofType:error: may work correctly for the cases for which 
I guess it was intended (as described by the NSDocument Class Reference), it 
doesn't seem to work for this case, for reasons unknown.

The best work-around I've found is to add a file reference URL to my NSDocument 
subclass, and set it in an override of setFileURL:. Then in an override of 
presentedItemDidMoveToURL: I test if the saved file reference URL is the same 
as the new URL, and do nothing if they're not the same file. That seems to 
work, but it's a bit of a hack, and I'd really like to understand if NSDocument 
is simply broken in this regard, or why setFileURL: does not work and what is 
the correct and reliable way to change the URL for an open document.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Unwanted presentedItemDidMoveToURL: for old file after using setFileURL: to specify a new file

2013-09-16 Thread Kyle Sluder
On Sat, Sep 14, 2013, at 01:14 PM, Brian Clark wrote:
 I'm hoping someone can suggest the correct way to deal with the following
 problem.
 
 For an image viewing app i display a file in the usual way in an
 NSDocument. setFileURL: is properly called by NSDocument's
 _initWithContentsOfURL:ofType:error:.
 
 I now want to display the next file in the folder, and move the old file
 to the Trash. To do this I do the necessary file reading tasks and call
 setFileURL: with the new file URL. I then move the old file to the trash
 (using NSFileManager 's trashItemAtURL:resultingItemURL:error: but using
 different methods gives the same result.)
 
 Prior to 10.7 this worked fine and gave the desired result. Under 10.8,
 shortly after I load the new file and call setFileURL: with the new file
 URL as described above, I see a presentedItemDidMoveToURL: call with the
 old file URL. From that point on, the document has the wrong URL
 associated with it.

Can you post your code for this?

One thing that comes to mind: you need to serialize against the incoming
file presenter notifications (delivered on the queue returned by
-presentedItemOperationQueue). Otherwise there's no guarantee that the
file coordination subsystem will have seen and confirmed your
relinquishing of the old URL by the time you start dealing with the new
one.

Furthermore, the NSFilePresenter protocol doesn't give you a way to
inform the system that the presentedItemURL of the presenter has
changed. You should make sure that NSDocument is calling
+removeFilePresenter: and +addFilePresenter: as part of its -setFIleURL:
action.

To be honest, I'm not even sure it's possible to do what you want to do.
You might need to open up the next file as a new document.

--Kyle Sluder
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Unwanted presentedItemDidMoveToURL: for old file after using setFileURL: to specify a new file

2013-09-16 Thread Kevin Perry
Re-using a single NSDocument instance to represent several different files is 
certainly atypical…

But, I suspect the problem here is that you're not using File Coordination when 
reading in the contents of the new file. By not doing that, you're not giving 
File Coordination the hint that it needs to check back with your 
NSFilePresenter (the NSDocument) for its presentedItemURL. When you read in the 
contents of the new file you should:

1) Start a File Access with -performSynchronousFileAccessUsingBlock: or 
-performAsynchronousFileAccessUsingBlock
2) Create an NSFileCoordinator instance with the NSDocument as the 
NSFilePresenter passed in the initializer.
3) Using that NSFileCoordinator, take a coordinated read of the target file
4) Inside the coordinated read: read the contents of the new file 
(-revertToContentsOfURL:ofType:error: is probably the most correct here, as it 
will update -fileURL, -fileModificationDate, -fileType, change counts, and 
other internal state as necessary)

After the coordinated read, NSFileCoordinator should re-invoke 
-presentedItemURL (which returns [self fileURL] by default), notice the URL has 
changed, and disassociate the NSFilePresenter state from the previous URL. This 
should prevent you from getting any unwanted NSFilePresenter messages.

-KP

On Sep 16, 2013, at 10:04 AM, Brian Clark ba-cl...@comcast.net wrote:

 
 On Sep 16, 2013, at 4:38 AM, Mike Abdullah mabdul...@karelia.com wrote:
 
 
 On 14 Sep 2013, at 21:14, Brian Clark ba-cl...@comcast.net wrote:
 
 I'm hoping someone can suggest the correct way to deal with the following 
 problem.
 
 For an image viewing app i display a file in the usual way in an 
 NSDocument. setFileURL: is properly called by NSDocument's 
 _initWithContentsOfURL:ofType:error:.
 
 I now want to display the next file in the folder, and move the old file to 
 the Trash. To do this I do the necessary file reading tasks and call 
 setFileURL: with the new file URL. I then move the old file to the trash 
 (using NSFileManager 's trashItemAtURL:resultingItemURL:error: but using 
 different methods gives the same result.)
 
 What are the necessary file reading tasks? Rather than call -setFileURL: 
 yourself, have you tried calling -revertToContentsOfURL:ofType:error: 
 instead? The top of the class documentation briefly notes that it should 
 always be used for re-reading documents.
 
 The necessary tasks are readFromURL:ofType:error: and the other chores 
 associated with setting up the document state for the different image file.
 
 Using -revertToContentsOfURL:ofType:error: instead does not work. After doing 
 this NSDocument still seems to treat the old URL as the file's document, and 
 I still get presentedItemDidMoveToURL: for the old file URL when it is moved 
 to the Trash AFTER I-ve called revertToContentsOfURL:ofType:error:. While 
 revertToContentsOfURL:ofType:error: may work correctly for the cases for 
 which I guess it was intended (as described by the NSDocument Class 
 Reference), it doesn't seem to work for this case, for reasons unknown.
 
 The best work-around I've found is to add a file reference URL to my 
 NSDocument subclass, and set it in an override of setFileURL:. Then in an 
 override of presentedItemDidMoveToURL: I test if the saved file reference URL 
 is the same as the new URL, and do nothing if they're not the same file. That 
 seems to work, but it's a bit of a hack, and I'd really like to understand if 
 NSDocument is simply broken in this regard, or why setFileURL: does not work 
 and what is the correct and reliable way to change the URL for an open 
 document.
 
 
 ___
 
 Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
 
 Please do not post admin requests or moderator comments to the list.
 Contact the moderators at cocoa-dev-admins(at)lists.apple.com
 
 Help/Unsubscribe/Update your Subscription:
 https://lists.apple.com/mailman/options/cocoa-dev/kperry%40apple.com
 
 This email sent to kpe...@apple.com


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Unwanted presentedItemDidMoveToURL: for old file after using setFileURL: to specify a new file

2013-09-16 Thread Brian Clark

On Sep 16, 2013, at 12:24 PM, Kevin Perry kpe...@apple.com wrote:

 Re-using a single NSDocument instance to represent several different files is 
 certainly atypical…

True, and I don't know what other similar applications so, but for some 
applications that are viewers it makes sense to let the user move forwards and 
backwards through a folder to display the file using the same window rather 
than opening and closing a window for each file. IT's mre efficient and a more 
pleasant experience for the user.

 But, I suspect the problem here is that you're not using File Coordination 
 when reading in the contents of the new file. By not doing that, you're not 
 giving File Coordination the hint that it needs to check back with your 
 NSFilePresenter (the NSDocument) for its presentedItemURL. When you read in 
 the contents of the new file you should:
 
 1) Start a File Access with -performSynchronousFileAccessUsingBlock: or 
 -performAsynchronousFileAccessUsingBlock
 2) Create an NSFileCoordinator instance with the NSDocument as the 
 NSFilePresenter passed in the initializer.
 3) Using that NSFileCoordinator, take a coordinated read of the target file
 4) Inside the coordinated read: read the contents of the new file 
 (-revertToContentsOfURL:ofType:error: is probably the most correct here, as 
 it will update -fileURL, -fileModificationDate, -fileType, change counts, and 
 other internal state as necessary)

Thanks! That seems to have worked.

It *is* necessary to use -revertToContentsOfURL:ofType:error: rather than 
-readFromURL:ofType:error:. And it's necessary as you suggested to do this 
inside a File Access with an NSFileCoordinator. Simply using 
-revertToContentsOfURL:ofType:error: without these doesn't work.

Thanks for your help.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com