NSDocument は で復元可能な状態をエンコードし-encodeRestorableStateWithCoder:
、 NSDocumentController はドキュメントの復元可能な状態をデコードし、 でドキュメントを再度開く役割を果たし+restoreWindowWithIdentifier:state:completionHandler:
ます。の役立つコメントを参照してくださいNSDocumentRestoration.h
。
NSDocument が URL をエンコードするとき、NSURL のブックマーク メソッドを使用しているように見えます。問題は、これらの方法がファイル システムの URL でしか機能しないことです。(ファイル以外の URL はエンコードされる可能性がありますが、適切にデコードされません。)
この問題を解決するには、カスタム スキームを使用する NSDocument インスタンスのエンコードをオーバーライドし、同様にそれらのドキュメントのデコードをオーバーライドします。
NSDocument サブクラス:
- (void) encodeRestorableStateWithCoder:(NSCoder *) coder {
if ([self.fileURL.scheme isEqualToString:@"customscheme"])
[coder encodeObject:self.fileURL forKey:@"MyDocumentAutoreopenURL"];
else
[super encodeRestorableStateWithCoder:coder];
}
NSDocumentController サブクラス:
+ (void) restoreWindowWithIdentifier:(NSString *) identifier
state:(NSCoder *) state
completionHandler:(void (^)(NSWindow *, NSError *)) completionHandler {
NSURL *autoreopenURL = [state decodeObjectForKey:@"MyDocumentAutoreopenURL"];
if (autoreopenURL) {
[[self sharedDocumentController]
reopenDocumentForURL:autoreopenURL
withContentsOfURL:autoreopenURL
display:NO
completionHandler:^(NSDocument *document, BOOL documentWasAlreadyOpen, NSError *error) {
NSWindow *resultWindow = nil;
if (!documentWasAlreadyOpen) {
if (![[document windowControllers] count])
[document makeWindowControllers];
if (1 == document.windowControllers.count)
resultWindow = [[document.windowControllers objectAtIndex:0] window];
else {
for (NSWindowController *wc in document.windowControllers)
if ([wc.window.identifier isEqual:identifier]) {
resultWindow = wc.window;
break;
}
}
}
completionHandler(resultWindow, error);
}
];
} else
[super restoreWindowWithIdentifier:identifier
state:state
completionHandler:completionHandler];
}
動作または完了ハンドラーは、NSDocumentRestoration.h の Apple のメソッド コメントに従い、のとほぼ同じである必要がありますsuper
。