macOS용 앱을 swift 3.0 기반으로 NSNotification을 사용하여 간단한 채팅앱을 구현해본다.
* AppDelegate.swift
메뉴의 File > New를 선택하면 새로운 윈도우컨트롤러가 생성되어야 한다.
이를 위해 위 코드를 작성한다.
var windowControllers: [ChatWindowController] = []
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
NSLog("applicationDidFinishLaunching")
addWindowController()
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
// MARK: - Actions
@IBAction func displayNewWindow(_ sender: NSMenuItem) {
addWindowController()
}
// MARK: - Helpers
func addWindowController() {
NSLog("addWindowController")
let windowController = ChatWindowController()
windowController.showWindow(self)
windowControllers.append(windowController)
}
메뉴와 displayNewWindow를 연결한다.
* ChatWindowController
ChatWindowControllerDidSendMessageNotification는 노티피케이션의 명칭이되고
ChatWindowControllerMessageKey 노티피케이션에 전달할 메시지의 키가 된다.
import Cocoa
private let ChatWindowControllerDidSendMessageNotification = "com.bignerdranch.chatter.ChatWindowControllerDidSendMessageNotification"
private let ChatWindowControllerMessageKey = "com.bignerdranch.chatter.ChatWindowControllerMessageKey"
class ChatWindowController: NSWindowController {
dynamic var log: NSAttributedString = NSAttributedString(string: "")
dynamic var message: String?
// NSTextView does not support weak references.
@IBOutlet var textView: NSTextView!
override var windowNibName: String {
return "ChatWindowController"
}
TextView의 Bindings Inspector에서 Value를 설정한다.
Bind to 에 체크해야하고
File's Owner로 선택한다.
Model Key Path는 log를 오타나지 않도록 주의하여 타이핑한다.
TextField를 선택하고
Bindings Inspector를 선택하고
Value항목에서 Bind to 체크, File's Owner를 선택한다.
Model Key Path는 message 변수를 타이핑하여 연결한다.
windowDidLoad() 델리게이트에 노티피케이션을 등록하는 구문을 추가한다.
selector를 지정할때 클래스명을 포함한 function명을 지정하는것이 특징이다.
override func windowDidLoad() {
super.windowDidLoad()
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self,
selector: #selector(ChatWindowController.receiveDidSendMessageNotification(_:)),
name: NSNotification.Name(rawValue: ChatWindowControllerDidSendMessageNotification),
object: nil)
}
* 윈도우컨트롤러가 종료되면 노티피케이션도 같이 제거될수 있도록 한다.
deinit {
let notificationCenter = NotificationCenter.default
notificationCenter.removeObserver(self)
}
* 사용자가 버튼을 누르게 되면 비로소 노티피케이션이 발송되도록 처리한다.
메시지는 Dictionary형태로 전달하면 된다.
// MARK: - Actions
@IBAction func send(_ sender: NSButton) {
sender.window?.endEditing(for: nil)
if let message = message {
let userInfo = [ChatWindowControllerMessageKey : message]
let notificationCenter = NotificationCenter.default
notificationCenter.post(name: Notification.Name(rawValue: ChatWindowControllerDidSendMessageNotification),
object: self,
userInfo: userInfo)
}
message = ""
}
Button의 IBAction이 send function과 제대로 연결이 되어야 한다.
* 노티피케이션이 모든 객체에 전체 발송되고 이를 수신할 리시버가될 델리케이션의 본문을 구현한다.
log.mutableCopy() log변수에서 복사한다음 메시지를 추가하여
mutableLog.copy()하여 다시 복사한 다음 log에 대입하여 준다.
function명에 copy가 들어간 것으로 보아 값을 새로운영역에 복사하여 만들어주는걸 알수 있다.
ARC가 내부적으로 동작할텐데 이부분도 심도있게 이해하면 좋을것이다.
// MARK: - Notifications
// ChatWindowControllerDidSendMessageNotification
func receiveDidSendMessageNotification(_ note: Notification) {
let mutableLog = log.mutableCopy() as! NSMutableAttributedString
if log.length > 0 {
mutableLog.append(NSAttributedString(string: "\n"))
}
let userInfo = note.userInfo! as! [String : String]
let message = userInfo[ChatWindowControllerMessageKey]!
let logLine = NSAttributedString(string: message)
mutableLog.append(logLine)
log = mutableLog.copy() as! NSAttributedString
textView.scrollRangeToVisible(NSRange(location: log.length, length: 0))
}
'TIP-맥OS' 카테고리의 다른 글
맥용 엑셀에서 불러오기 한후 한글이 깨지는 경우 해결방법 (0) | 2017.08.03 |
---|---|
macOS에서 코너스톤 SVN 사용하기 (0) | 2017.07.14 |
macOS에서 디렉토리내의 모든 파일목록 추출하기 (linux, unix 동일) (0) | 2017.06.26 |
macOS용 XCode 스토리보드 프로젝트 XIB프로젝트로 변경하기 (0) | 2017.06.25 |
macOS 파일 유형에 맞는 확장자와 아이콘 설정하기 (0) | 2017.05.14 |