I have a simple class that (once fleshed out) will constitute the data handled by an NSDocument subclass. But, I am getting stuck right out of the gate trying to save/init the class using NSDocument's data(ofType:) and read(from: ofType:) methods.
The error I am seeing in the debugger is:
[General] *** -encodeObject:forKey: only defined for abstract class. Define -[NSArchiver encodeObject:forKey:]!
My Document subclass of NSDocument looks like:
class Document: NSDocument
{
private(set) var coverTree = CoverTree()
// ... skipping boilerplate init and makeWindowControllers methods
override class func autosavesInPlace() -> Bool {
return false
}
override func data(ofType typeName: String) throws -> Data
{
return NSArchiver.archivedData(withRootObject: coverTree)
}
override func read(from data: Data, ofType typeName: String) throws
{
if let ct = NSUnarchiver(forReadingWith: data)?.decodeObject() as? CoverTree
{
coverTree = ct
}
}
}
and my CoverTree class currently looks like:
import Cocoa
class CoverTree: NSObject, NSCoding
{
private(set) var generated = false
let creationStamp : String
override init()
{
let df = DateFormatter()
df.dateStyle = .full
df.timeStyle = .full
creationStamp = df.string(from: Date())
super.init()
}
required init(coder decoder:NSCoder)
{
creationStamp = decoder.decodeObject(forKey: "creation") as! String
}
func encode(with coder: NSCoder)
{
coder.encode(self.creationStamp, forKey:"creation")
}
func generate( dataSet : DataSet) -> Void
{
generated = true
}
}
The error occurs when executing the only line in CoverTree::encode()
I have been ripping my hair out looking for examples both on and off StackOverflow. What I have appears to follow all the suggested patterns/snippets.
Searches on the error string suggest that the error is due to using NSCoder rather than NSKeyedArchiver.... but if I change the signature of encode to encode(with coder:NSKeyedArchiver), I get an error that CoverTree is not compliant with NSCoding.
What am I missing?
Thanks much, mike
Here is the entire stack trace if this is of any help:
2017-09-11 09:55:44.682537-0400 coverTreeDemo[40650:3798144] [General] *** -encodeObject:forKey: only defined for abstract class. Define -[NSArchiver encodeObject:forKey:]!
2017-09-11 09:55:44.691417-0400 coverTreeDemo[40650:3798144] [General] (
0 CoreFoundation 0x00007fffa3ae357b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fffb8d3c1da objc_exception_throw + 48
2 CoreFoundation 0x00007fffa3b60c55 +[NSException raise:format:] + 197
3 Foundation 0x00007fffa5621abe NSRequestConcreteImplementation + 229
4 coverTreeDemo 0x0000000100003583 _TFC13coverTreeDemo9CoverTree6encodefT4withCSo7NSCoder_T_ + 163
5 coverTreeDemo 0x00000001000035fa _TToFC13coverTreeDemo9CoverTree6encodefT4withCSo7NSCoder_T_ + 58
6 Foundation 0x00007fffa54922e1 -[NSArchiver encodeRootObject:] + 164
7 Foundation 0x00007fffa5491a66 +[NSArchiver archivedDataWithRootObject:] + 141
8 coverTreeDemo 0x0000000100003f3b _TFC13coverTreeDemo8Document4datafzT6ofTypeSS_V10Foundation4Data + 491
9 coverTreeDemo 0x000000010000402b _TToFC13coverTreeDemo8Document4datafzT6ofTypeSS_V10Foundation4Data + 91
10 AppKit 0x00007fffa190121c -[NSDocument writeToURL:ofType:error:] + 812
11 AppKit 0x00007fffa1900ead -[NSDocument writeToURL:ofType:forSaveOperation:originalContentsURL:error:] + 445
12 AppKit 0x00007fffa208bbb1 -[NSDocument(NSDocumentSaving) _writeSafelyToURL:ofType:forSaveOperation:forceTemporaryDirectory:error:] + 915
13 AppKit 0x00007fffa208c8b7 -[NSDocument(NSDocumentSaving) _writeSafelyToURL:ofType:forSaveOperation:error:] + 28
14 AppKit 0x00007fffa190089e -[NSDocument writeSafelyToURL:ofType:forSaveOperation:error:] + 355
15 AppKit 0x00007fffa20978c5 __85-[NSDocument(NSDocumentSaving) _saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke_2.1116 + 233
16 AppKit 0x00007fffa20977cd __85-[NSDocument(NSDocumentSaving) _saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke.1113 + 454
17 AppKit 0x00007fffa2095903 __85-[NSDocument(NSDocumentSaving) _saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke_2.969 + 2071
18 Foundation 0x00007fffa56e8e48 __85-[NSFileCoordinator(NSPrivate) _coordinateWritingItemAtURL:options:error:byAccessor:]_block_invoke.404 + 226
19 Foundation 0x00007fffa56e88ab -[NSFileCoordinator(NSPrivate) _withAccessArbiter:invokeAccessor:orDont:andRelinquishAccessClaim:] + 493
20 Foundation 0x00007fffa557e206 -[NSFileCoordinator(NSPrivate) _coordinateWritingItemAtURL:options:error:byAccessor:] + 862
21 AppKit 0x00007fffa2092dd0 -[NSDocument(NSDocumentSaving) _fileCoordinator:coordinateReadingContentsAndWritingItemAtURL:byAccessor:] + 387
22 AppKit 0x00007fffa20950d4 __85-[NSDocument(NSDocumentSaving) _saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke.964 + 544
23 AppKit 0x00007fffa209462b __85-[NSDocument(NSDocumentSaving) _saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke + 508
24 AppKit 0x00007fffa1b2abd6 -[NSDocument(NSDocumentSerializationAPIs) continueFileAccessUsingBlock:] + 222
25 AppKit 0x00007fffa1b2b477 -[NSDocument(NSDocumentSerializationAPIs) _performFileAccess:] + 782
26 AppKit 0x00007fffa2094429 -[NSDocument(NSDocumentSaving) _saveToURL:ofType:forSaveOperation:completionHandler:] + 92
27 AppKit 0x00007fffa194b2a8 __85-[NSDocument saveToURL:ofType:forSaveOperation:delegate:didSaveSelector:contextInfo:]_block_invoke_2 + 256
28 AppKit 0x00007fffa18ba1e2 -[NSDocument _commitEditingThenContinue:] + 474
29 AppKit 0x00007fffa18b9fff -[NSDocument _commitEditingWithDelegate:didSomethingSelector:contextInfo:thenContinue:] + 92
30 AppKit 0x00007fffa194b196 __85-[NSDocument saveToURL:ofType:forSaveOperation:delegate:didSaveSelector:contextInfo:]_block_invoke + 444
31 AppKit 0x00007fffa1b2a305 -[NSDocument(NSDocumentSerializationAPIs) performActivityWithSynchronousWaiting:usingBlock:cancellationHandler:] + 475
32 AppKit 0x00007fffa194afd4 -[NSDocument saveToURL:ofType:forSaveOperation:delegate:didSaveSelector:contextInfo:] + 113
33 AppKit 0x00007fffa2090ff1 __104-[NSDocument(NSDocumentSaving) _runModalSavePanelForSaveOperation:delegate:didSaveSelector:contextInfo:]_block_invoke.595 + 113
34 AppKit 0x00007fffa1b2a4d3 -[NSDocument(NSDocumentSerializationAPIs) _continueActivityUsingBlock:] + 320
35 AppKit 0x00007fffa2090de5 __104-[NSDocument(NSDocumentSaving) _runModalSavePanelForSaveOperation:delegate:didSaveSelector:contextInfo:]_block_invoke_2.580 + 506
36 AppKit 0x00007fffa209097c __104-[NSDocument(NSDocumentSaving) _runModalSavePanelForSaveOperation:delegate:didSaveSelector:contextInfo:]_block_invoke.561 + 1500
37 AppKit 0x00007fffa1c558b9 -[NSSavePanel _didEndSheet:returnCode:contextInfo:] + 95
38 AppKit 0x00007fffa17c3b84 -[NSWindow _endWindowBlockingModalSession:returnCode:] + 308
39 AppKit 0x00007fffa1c581c6 -[NSSavePanel overwriteAlertDidEnd:returnCode:contextInfo:] + 256
40 AppKit 0x00007fffa197a1e3 -[NSAlert didEndAlert:returnCode:contextInfo:] + 90
41 AppKit 0x00007fffa17c3b84 -[NSWindow _endWindowBlockingModalSession:returnCode:] + 308
42 AppKit 0x00007fffa18239e3 -[NSAlert buttonPressed:] + 107
43 libsystem_trace.dylib 0x00007fffb984f3a7 _os_activity_initiate_impl + 53
44 AppKit 0x00007fffa1cd0721 -[NSApplication(NSResponder) sendAction:to:from:] + 456
45 AppKit 0x00007fffa17b4cc4 -[NSControl sendAction:to:] + 86
46 AppKit 0x00007fffa17b4bec __26-[NSCell _sendActionFrom:]_block_invoke + 136
47 libsystem_trace.dylib 0x00007fffb984f3a7 _os_activity_initiate_impl + 53
48 AppKit 0x00007fffa17b4b44 -[NSCell _sendActionFrom:] + 128
49 AppKit 0x00007fffa17f7539 -[NSButtonCell _sendActionFrom:] + 98
50 libsystem_trace.dylib 0x00007fffb984f3a7 _os_activity_initiate_impl + 53
51 AppKit 0x00007fffa17b3426 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2481
52 AppKit 0x00007fffa17f7272 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 798
53 AppKit 0x00007fffa17b1ddb -[NSControl mouseDown:] + 832
54 AppKit 0x00007fffa1e4c24f -[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:] + 6341
55 AppKit 0x00007fffa1e48a6c -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 1942
56 AppKit 0x00007fffa1e47f0a -[NSWindow(NSEventRouting) sendEvent:] + 541
57 AppKit 0x00007fffa1ccc681 -[NSApplication(NSEvent) sendEvent:] + 1145
58 AppKit 0x00007fffa1547427 -[NSApplication run] + 1002
59 AppKit 0x00007fffa1511e0e NSApplicationMain + 1237
60 coverTreeDemo 0x0000000100002cbd main + 13
61 libdyld.dylib 0x00007fffb961d235 start + 1
)
The problem is that you refer to in your NSDocument subclass to NSArchiver and NSUnarchiver. That's wrong. These classes are deprecated. You should be using NSKeyedArchiver and NSKeyedUnarchiver, which replace them. The docs are quite clear about this:
In macOS 10.2 and later, NSArchiver and NSUnarchiver have been replaced by NSKeyedArchiver and NSKeyedUnarchiver respectively