8

Apple documentation suggests to override an NSDocument convenience init (initWithType:error:) as described here.

However, as this is a convenience init, I cannot override it. But I still need to execute some code when a new document is created. I do not want to execute that code when I load a document.

In my particular case I try to initialise an NSPersistentDocument, but I doubt that is relevant.

What shall I do?

Wizard of Kneup
  • 1,863
  • 1
  • 18
  • 35
  • you make a subclass of NSPersistentDocument... then you set that in your info.plist or wherever that goes... so that your application associates that class with the type – Grady Player Dec 29 '14 at 21:09
  • ok, question allows different interpretations. Sorry. I need to execute code after creation. That is what the convenience init allows. But I am not sure where to do this now, when I can no longer override this particular init. – Wizard of Kneup Dec 30 '14 at 08:52
  • What do you mean that you can't override the init? – Grady Player Dec 30 '14 at 14:24
  • According to documentation, I should override the convenience init (initWithType:error:). But a convenience init cannot call a super.init, only a self.init (= designated init). Hence, I cannot override the initialiser. – Wizard of Kneup Dec 30 '14 at 20:32
  • Just found this: If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initializers. – Wizard of Kneup Nov 21 '15 at 13:45

2 Answers2

11

Above answer works for Swift 1.

It has to be changed to answer below in Swift 2:

convenience init(type typeName: String) throws {
    self.init()
    // Rest of initialization code here
}

This was answered here: http://meandmark.com/blog/2015/07/nsdocument-initwithtype-in-swift-2/

Reposted for convenience since this is a common problem.

El Architect
  • 138
  • 1
  • 5
8

To execute init code for a new document:

// Create new document (only called for new documents)
convenience init?(type typeName: String, error outError: NSErrorPointer) {
    self.init()
    fileType = typeName
    // add your own initialisation for new document here
}

The problem in Swift is that you can not call a convenience initializer in super. Instead you must delegate to a designated initializer in self. This means that you can't take advantage of any of supers convenience initializers and you must implement the initialization your self---hence fileType = typeName above. As much as I like Swift, I find this stupid: what's the point of re-implementing code that could be reused!?

Melodius
  • 2,505
  • 3
  • 22
  • 37