Last active
May 30, 2018 07:31
-
-
Save jeanetienne/a63f21618d8f073d99e2b9d81edc3a5c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Logic necessary to implement a "closing handler" for a NSDocument | |
// | |
// This is inspired by: | |
// - https://stackoverflow.com/questions/49343307/best-practice-to-implement-canclosewithdelegateshouldclosecontextinfo | |
// - https://github.com/keith/radars/blob/master/NSDocumentSwiftAnnotations/NSDocumentSwiftAnnotations/Document.swift | |
// Keith's supporting documentation for his radar submission: http://www.openradar.me/33422662 | |
// Documentation: | |
// - https://developer.apple.com/library/content/releasenotes/AppKit/RN-AppKitOlderNotes/ | |
// Paragraph called: "Advice for Overriders of Methods that Follow the delegate:didSomethingSelector:contextInfo: Pattern" | |
// | |
// I'm not even sure I understand all that's happening here, use it at you own risk! | |
// | |
class MyDocument: NSDocument { | |
private var originalShouldCloseSelectorBlock : ((Bool) -> Void)? = nil | |
override func canClose(withDelegate delegate: Any, shouldClose shouldCloseSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) { | |
guard let selector = shouldCloseSelector, let context = contextInfo, | |
let object = delegate as? NSObject, let objcClass = objc_getClass(object.className) as? AnyClass, | |
let method = class_getMethodImplementation(objcClass, selector) else { | |
super.canClose(withDelegate: delegate, shouldClose: shouldCloseSelector, contextInfo: contextInfo) | |
return | |
} | |
typealias FunctionSignature = @convention(c) (AnyObject, Selector, AnyObject, Bool, UnsafeMutableRawPointer?) -> Void | |
let function = unsafeBitCast(method, to: FunctionSignature.self) | |
self.originalShouldCloseSelectorBlock = {[unowned object, selector, context] (flag) -> Void in | |
function(object, selector, self, flag, context) | |
} | |
let delegate: Any = self | |
let shouldCloseSelector: Selector = #selector(document(_:shouldClose:contextInfo:)) | |
super.canClose(withDelegate: delegate, shouldClose: shouldCloseSelector, contextInfo: contextInfo) | |
} | |
@objc func document(_ document: NSDocument, shouldClose: Bool, contextInfo: UnsafeMutableRawPointer?) { | |
// | |
// This is where you can do you own document-closing related logic | |
// | |
self.originalShouldCloseSelectorBlock?(shouldClose) | |
self.originalShouldCloseSelectorBlock = nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment