NSTextView / NSViewController \ NSNotification用于SWIFT {Mac}应用程序的控制台日志功能

时间:2017-05-27 08:22:12

标签: swift macos nstextview nsviewcontroller nsnotification

我正在尝试开发一个应用程序,其中包含一个带有单个NSTextView的StoryBoard,我想用它来记录应用程序事件和用户反馈。我从主视图中的复选框开关加载视图(默认情况下,当应用程序启动时,控制台日志视图处于打开状态)。所有这些都适用于应用程序启动,第二个视图使用viewDidLoad()函数预期的文本。

控制台日志视图的NSViewController类是:

class ConsoleLogViewController: NSViewController,NSTextViewDelegate {

@IBOutlet var textViewConsoleLog: NSTextView!

override func viewWillDisappear() {
    (representedObject as! NSButton).isEnabled = true
    (representedObject as! NSButton).state = NSOffState
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do view setup here.

    textViewConsoleLog.delegate = self
    textViewConsoleLog.string = "All new journal events are logged to this window"
    textViewConsoleLog.string?.append("\n")
    textViewConsoleLog.string?.append("*********************************************")
    textViewConsoleLog.string?.append("\n")
    textViewConsoleLog.string?.append("\n")
} // END OF viewDidLoad()


func addLogToConsoleWindow(newLogEntry: String) {
    textViewConsoleLog.string? = (newLogEntry)
    textViewConsoleLog.string?.append("\n")
} // END OF addLogToConsoleWindow()

} //结束于ConsoleLogViewController

使用以下函数调用从主视图控制器(在下图中命名为“Control”)启动视图:

    func showConsoleLogView() {
    let buttonCall = chkBoxConsoleLog
    performSegue(withIdentifier: "sequeConsoleView", sender: buttonCall)
}  //  END OF showConsoleLogView()

在主视图控制器中,我创建了一个ConsoleLogViewController实例,然后尝试使用addLogToConsoleWindow函数将附加日志信息附加到textViewConsoleLog。主视图控制器中相关的代码片段为:

    let consoleOutputPrintStatement = ConsoleLogViewController()  // Create an instance of ConsoleLogViewController to allow logging to the new console window

consoleOutputPrintStatement.addLogToConsoleWindow(newLogEntry: "Loading journal files")

然而,当我运行应用程序并尝试编写其他文本行时,我得到fatal error: unexpectedly found nil while unwrapping an Optional value。很明显,textViewConsoleLog对象是nil并且正在创建错误。

我认为问题在于我正在创建该类的另一个实例,因此我试图将其他文本附加到尚未启动的textViewConsoleLog对象(或类似的东西!)。

该应用在首次运行时看起来像这样:

enter image description here

所以 - 我是否正试图使用​​NSTextView向控制台开发日志记录功能?或者我是否关闭但需要使用NSTextView的不同方法才能使其正常工作?如何使用从其他viewControllers生成的相关字符串更新NSTextField中的文本?

高度赞赏的任何帮助或指导。

1 个答案:

答案 0 :(得分:0)

好的 - 我最终使用NSNotification解决了一个解决方案 - 事后看来这很明显。

控制台日志视图中的相关代码如下所示,正在设置类以使用addObserver方法从NotificationCenter接收通知。

class ConsoleLogViewController: NSViewController,NSTextViewDelegate {

@IBOutlet var textViewConsoleLog: NSTextView!

let controlCentreDidSendConsoleNotification = "TCCEDJ.controlCentreDidSendConsoleNotification"
let controlCentreDidSendConsoleNotificationMessageKey = "TCCEDJ.controlCentreDidSendConsoleNotificationMessageKey"


override func viewWillDisappear() {
    (representedObject as! NSButton).isEnabled = true
    (representedObject as! NSButton).state = NSOffState
}


override func viewDidLoad() {
    super.viewDidLoad()

    textViewConsoleLog.delegate = self
    textViewConsoleLog.string = "All new journal events are logged to this window"
    textViewConsoleLog.string?.append("\n")
    textViewConsoleLog.string?.append("*********************************************")
    textViewConsoleLog.string?.append("\n")
    textViewConsoleLog.string?.append("\n")

    //  set up notification centre
    let notificationCentre = NotificationCenter.default
    notificationCentre.addObserver(self, selector: #selector(addLogToConsoleWindow), name: NSNotification.Name(rawValue: controlCentreDidSendConsoleNotification), object: nil)
} // END OF viewDidLoad()


@objc func addLogToConsoleWindow(newLogEntry: NSNotification) {

    let userInfo = newLogEntry.userInfo as! [String: String]
    let newLogEntryString = userInfo[controlCentreDidSendConsoleNotificationMessageKey]!

    textViewConsoleLog.string?.append(newLogEntryString)
    textViewConsoleLog.string?.append("\n")
    textViewConsoleLog.scrollRangeToVisible(NSMakeRange((textViewConsoleLog.string?.characters.count)! - 1, 0))
} // END OF addLogToConsoleWindow()

} //结束于ConsoleLogViewController

主视图控制器中的相关代码是:

    // Set up variables to use with notification centre
let controlCentreDidSendConsoleNotification = "TCCEDJ.controlCentreDidSendConsoleNotification"
let controlCentreDidSendConsoleNotificationMessageKey = "TCCEDJ.controlCentreDidSendConsoleNotificationMessageKey"

    let testLog = [controlCentreDidSendConsoleNotificationMessageKey: "Test log on button push"]
    let notificationCentre = NotificationCenter.default
    notificationCentre.post(name: NSNotification.Name(rawValue: controlCentreDidSendConsoleNotification), object: self, userInfo: testLog)

所有现在都适用于我正在寻找的行为。