• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: My method causes DATA LOSS! (was: Can I use the restore/auto-save loading functions for imports?)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: My method causes DATA LOSS! (was: Can I use the restore/auto-save loading functions for imports?)


  • Subject: Re: My method causes DATA LOSS! (was: Can I use the restore/auto-save loading functions for imports?)
  • From: Daryle Walker <email@hidden>
  • Date: Tue, 07 Mar 2017 00:16:16 -0500

> On Mar 6, 2017, at 7:05 PM, Daryle Walker <email@hidden> wrote:
>
>
>> On Mar 6, 2017, at 4:58 PM, Daryle Walker <email@hidden> wrote:
>>
>> The docs fo “NSDocumentController.reopenDocument(for: withContentsOf: display: completionHandler:)” mention it’s for app restore. It ultimately calls “NSDocument.init(for: withContentsOf: ofType:)”, which mentions autosaved documents. Do I have to restrict these methods for their documented purposes? Or can I use them for general code, like an import-document function? They look perfect; they load in a file’s data to a new document, but leave the document’s file-identity anonymous afterwards.
>
> I tried:
>
>> extension DocumentController {
>>
>>    /**
>>        An action method called by the Import command, it runs the modal Open panel and, based on the selected filenames, creates one or more `NSDocument` objects from the contents of the files, but stripping the file identities.
>>
>>        The method adds the newly created objects to the list of `NSDocument` objects managed by the document controller.  This method calls `reopenDocument(for:withContentsOf:display:completionHandler:)`, which actually creates the `NSDocument` objects.  The first parameter is set to `nil`, meaning the documents are initialized with the source data, but they don't point back to said source.
>>     */
>>    @IBAction func newDocumentFrom(_ sender: Any?) {
>>        self.beginOpenPanel {
>>            guard let files = $0 else { return }
>>
>>            for file in files {
>>                self.reopenDocument(for: nil, withContentsOf: file, display: true) {
>>                    if let error = $2 {
>>                        self.presentError(error)  // Ignore if recovery was done.
>>                    }
>>                    print("Document: \($0); Already open: \($1); Error: \($2)")
>>                }
>>            }
>>        }
>>    }
>>
>> }
>
> Do not do this.
>
> 1. When I load a file with normal open, then try my import action above, no new window appears because the document has already been open once.
> 2. When my import was the first action on the file, there is a window with that document’s data. But the file DISAPPEARS from the Finder! I guess using these functions not as planned marked the file as temporary and cleared it.
>
> Since I already created a NSDocumentController subclass, I could do it right. Maybe I first call the regular open functionality, then:
>
> A. If the document already exists, make a new unconnected copy with Duplicate.
> B. If the document didn’t exist, strip the file-URL and old file-name.

I actually unconditionally duplicate the loaded document and remove the first one if it wasn’t already open:

>     @IBAction func newDocumentFrom(_ sender: Any?) {
>         self.tryingImport = true
>         self.beginOpenPanel { possibleFiles in
>             self.tryingImport = false
>             guard let files = possibleFiles else { return }
>
>             for file in files {
>                 self.imports.append(file)
>                 self.openDocument(withContentsOf: file, display: false) { possibleDocument, alreadyOpen, possibleError in
>                     if let error = possibleError {
>                         self.presentError(error)  // Ignore any recovery
>                     }
>                     if alreadyOpen {
>                         self.imports.remove(at: self.imports.index(of: file)!)
>                     }
>                     if let document = possibleDocument {
>                         do {
>                             try self.duplicateDocument(withContentsOf: file, copying: true, displayName: document.displayName)
>                         } catch {
>                             self.presentError(error) // Ignore any recovery
>                         }
>                         if !alreadyOpen {
>                             document.close()
>                         }
>                     }
>                 }
>             }
>         }
>     }

It seems to be working so far. I have overrides of “addDocument” to not work if the file is in self.imports and of “runModalOpenPanel” to watch self.tryingImport and change the OK button accordingly (from “Open” to “Import”).

—
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com


_______________________________________________

Cocoa-dev mailing list (email@hidden)

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:

This email sent to email@hidden


References: 
 >Can I use the restore/auto-save loading functions for imports? (From: Daryle Walker <email@hidden>)
 >My method causes DATA LOSS! (was: Can I use the restore/auto-save loading functions for imports?) (From: Daryle Walker <email@hidden>)

  • Prev by Date: Re: Cocoa-dev Digest, Vol 14, Issue 78
  • Next by Date: Re: boundingRectForGlyphRange is very inaccurate
  • Previous by thread: My method causes DATA LOSS! (was: Can I use the restore/auto-save loading functions for imports?)
  • Next by thread: Re: Cocoa-dev Digest, Vol 14, Issue 78
  • Index(es):
    • Date
    • Thread