Re: Unwanted presentedItemDidMoveToURL: for old file after using setFileURL: to specify a new file
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
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
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
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
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
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
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