Converting a basic Cocoa application to a document-based application

后端 未结 4 1657
萌比男神i
萌比男神i 2021-02-07 18:51

My team and I have been working on an existing, non-document-based Cocoa application. This is our first Cocoa app, although we\'ve done a number of iOS apps thus far.

Th

相关标签:
4条回答
  • 2021-02-07 19:28

    Everything @Hans' answer provides is correct, but the final change that is needed is totally, stupidly trivial, but adds a nontrivial amount of functionality that comes with document-based apps:

    In the Main.storyboard file, the document element has an extra property that needs to be deleted: initialViewController="XXX-XX-XXX".

    It is probably the last thing on second line. Remove this, and the Save… menu option, along with a few other menu options, will properly be enabled by default, and the app will properly recognize the document object upon launch.

    0 讨论(0)
  • 2021-02-07 19:28

    This is more of an opinion than a direct answer, but if you're new to the Mac side and to document-based applications, your path of least resistance would definitely be to create a new doc-based Xcode project from the template and move your relevant code over, plugging it into the template places where needed.

    0 讨论(0)
  • 2021-02-07 19:49

    An often found suggestion is to create a new document based application and move all you existing code in there. This can be cumbersome for a large workspace with all kinds of stuff nicely configured. Let alone breaking version control.

    I took the following simple steps and it worked:

    • Generate a document based application
    • from this this generated project, copy the following section from the Info.plist (open the file with a normal text-editor):

      <key>CFBundleDocumentTypes</key>
      <array>
          <dict>
              <key>CFBundleTypeExtensions</key>
              <array>
                  <string>mydoc</string>
              </array>
              <key>CFBundleTypeIconFile</key>
              <string></string>
              <key>CFBundleTypeName</key>
              <string>DocumentType</string>
              <key>CFBundleTypeOSTypes</key>
              <array>
                  <string>????</string>
              </array>
              <key>CFBundleTypeRole</key>
              <string>Editor</string>
              <key>NSDocumentClass</key>
              <string>$(PRODUCT_MODULE_NAME).Document</string>
          </dict>
      </array>
      

      and paste it in the Info.plist file in your own project.

    • Copy Document.swift from the generated document-based project into your own project.

    • it contains a method:

      override func makeWindowControllers() {
          // Returns the Storyboard that contains your Document window.
          let storyboard = NSStoryboard(name: "Main", bundle: nil)
          let windowController = storyboard.instantiateController(withIdentifier: "Document Window Controller") as! NSWindowController
          self.addWindowController(windowController)
      }
      

      It creates a new window just the way you application normally would. If you storyboard has only one windowcontroller the 'withIDentifier'-field can contain something arbitrary. If you have more window controllers in your storyboard, the identifier needs to correspond to the right windowcontroller for new documents.

    0 讨论(0)
  • 2021-02-07 19:49

    Okay, this time I legitmately do have a solution to present.

    It turns out I had a "window" instance variable in SPDocumentInfo (which as you'd guess pointed to the NSWindow associated with the document). That appeared to caused a chain of events (or more likely, prevented a chain of events) which led to SPDocumentInfo's dealloc not being called when it should have. I didn't catch that when I was comparing my project to the sample doc-based project, because apparently SPDocument also has a member variable called "window" which is also connected to the relevant NSWindow. I saw that connection in the sample project, and it looked identical to my project's connection, so I didn't think twice about it.

    In other words, part of my problem was that I just coincidentally decided to connect up a "window" outlet NSDocument implementation, and didn't realize that I was actually shadowing a superclass variable (which I'm guessing is, unlike mine, configured as "assign" and not "retain").

    So, things seem okay at this point, and I think I can declare that it is indeed possible (and my nagging issue notwithstanding, generally painless) to convert from a non-doc-based app to a doc-based one.

    0 讨论(0)
提交回复
热议问题