The Correct Place to Migrate my NSDocument


Bill Pitcher
 

I have an App that needs to be upgraded (thanks App Store) and I want the new App to Open and migrate it’s old documents to the new versions document. With the new File Type and Extension.

All good, I can open both types in "override func read(from data: Data, ofType typeName: String) throws”.
And the internal data is all good.

But when it saves (Including the automagical save when quitting) the new migrated data gets put into the old file, keeping the old DocumentType and Extension. (If I change the file extension manually in Finder it then opens fine)

I get the feeling that either I’m no doing this in the right place or I’m missing something obvious.

Any advice or examples greatly appreciated.

cheers
Bill Pitcher
bill@...


Bill Pitcher
 

This works but it’s not right and throws a yucky message

let holdDoc = try NSDocumentController.shared.openUntitledDocumentAndDisplay(false) as! Document
// set the updated data
holdDoc.documentQuestions = self.documentQuestions
// show the new document
holdDoc.makeWindowControllers()
holdDoc.showWindows()
holdDoc.updateChangeCount(.changeDone)
// cancel 
throw NSError(domain: "Application", code: 1002, userInfo: [NSLocalizedDescriptionKey : "File Updated", NSLocalizedRecoverySuggestionErrorKey : "The new Untitled document has the information for " + (self.fileURL?.path)! ] )

From Apple’s - Additional Document Type Considerations
"If you want to automatically convert them to be saved as your new type, you can override the readFrom... methods in your NSDocument subclass to call super and then reset the filename and type afterwards. You should use setFileType: and setFileURL: to set an appropriate type and name for the new document. When setting the filename, make sure to strip the filename extension of the old type from the original filename, if it is there, and add the extension for the new type.”

But from NSDocument
"You cannot use this property to change the document’s format after it has already been opened or saved. This property records only the initial document format used when first opening or saving the file."

Call super what??? "Expected '.' or '[' after ‘super'"

Bill Pitcher
bill@...



On 12/05/2018, at 4:32 PM, Bill Pitcher <bill@...> wrote:

I have an App that needs to be upgraded (thanks App Store) and I want the new App to Open and migrate it’s old documents to the new versions document. With the new File Type and Extension.

All good, I can open both types in "override func read(from data: Data, ofType typeName: String) throws”.
And the internal data is all good.

But when it saves (Including the automagical save when quitting) the new migrated data gets put into the old file, keeping the old DocumentType and Extension. (If I change the file extension manually in Finder it then opens fine)

I get the feeling that either I’m no doing this in the right place or I’m missing something obvious. 

Any advice or examples greatly appreciated.

cheers
Bill Pitcher
bill@...








Bill Pitcher
 

I’m going to mark this as working now:

Set my DocumentController subclass as the main shared NSDocumentController
func applicationWillFinishLaunching(_ notification: Notification) {
_ = DocumentController.init()
}

class DocumentController: NSDocumentController {

override func makeDocument( withContentsOf contentsURL: URL,
ofType typeName: String) throws -> NSDocument {

if typeName == “CurrentVersion” {
return try super.makeDocument( withContentsOf: contentsURL, ofType: typeName)
}
let holdDocument = try self.makeUntitledDocument(ofType: "CurrentVersion") as! Document
try holdDocument.updateFromURL(fromURL: contentsURL)
return holdDocument
}
}

In the Document write the updateFromURL(fromURL: URL) that does the conversion and flag the document as self.hasBeenUpgraded = true
self.updateChangeCount(.changeDone) (this ensures the changes are saved if the user quits without saving)

when the document window has been displayed check hasBeenUpgraded and NSAlert the user that the Untiled Document has been upgraded.

NOTE: Document Type set to “Viewer" in Info.plist does NOT set NSDocument isInViewingMode, it does NOT open the document in an Untitled document. overriding isInViewingMode to true does disable Saving and messes with other options in the File menu, I gave up to this route.

Comments still very welcome!

cheers
Bill Pitcher
bill@...

On 13/05/2018, at 11:46 AM, Bill Pitcher <bill@...> wrote:

This works but it’s not right and throws a yucky message

let holdDoc = try NSDocumentController.shared.openUntitledDocumentAndDisplay(false) as! Document
// set the updated data
holdDoc.documentQuestions = self.documentQuestions
// show the new document
holdDoc.makeWindowControllers()
holdDoc.showWindows()
holdDoc.updateChangeCount(.changeDone)
// cancel
throw NSError(domain: "Application", code: 1002, userInfo: [NSLocalizedDescriptionKey : "File Updated", NSLocalizedRecoverySuggestionErrorKey : "The new Untitled document has the information for " + (self.fileURL?.path)! ] )

From Apple’s - Additional Document Type Considerations
"If you want to automatically convert them to be saved as your new type, you can override the readFrom... methods in your NSDocument subclass to call super and then reset the filename and type afterwards. You should use setFileType: and setFileURL: to set an appropriate type and name for the new document. When setting the filename, make sure to strip the filename extension of the old type from the original filename, if it is there, and add the extension for the new type.”

But from NSDocument
"You cannot use this property to change the document’s format after it has already been opened or saved. This property records only the initial document format used when first opening or saving the file."

Call super what??? "Expected '.' or '[' after ‘super'"

Bill Pitcher
bill@...



On 12/05/2018, at 4:32 PM, Bill Pitcher <bill@...> wrote:

I have an App that needs to be upgraded (thanks App Store) and I want the new App to Open and migrate it’s old documents to the new versions document. With the new File Type and Extension.

All good, I can open both types in "override func read(from data: Data, ofType typeName: String) throws”.
And the internal data is all good.

But when it saves (Including the automagical save when quitting) the new migrated data gets put into the old file, keeping the old DocumentType and Extension. (If I change the file extension manually in Finder it then opens fine)

I get the feeling that either I’m no doing this in the right place or I’m missing something obvious.

Any advice or examples greatly appreciated.

cheers
Bill Pitcher
bill@...