[ios] Swift의 NSNotificationCenter addObserver
Swift에서 옵저버를 기본 알림 센터에 어떻게 추가합니까? 배터리 잔량이 변경되면 알림을 보내는이 코드 줄을 이식하려고합니다.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
답변
Objective-C API와 동일하지만 Swift의 구문을 사용합니다.
스위프트 4.2 및 스위프트 5 :
NotificationCenter.default.addObserver(
self,
selector: #selector(self.batteryLevelChanged),
name: UIDevice.batteryLevelDidChangeNotification,
object: nil)
관찰자가 Objective-C 오브젝트에서 상속하지 않는 경우 메소드를 @objc
선택 자로 사용하려면 메소드 접 두부 를 사용해야합니다.
@objc private func batteryLevelChanged(notification: NSNotification){
//do stuff using the userInfo property of the notification object
}
답변
스위프트 4.0 및 Xcode 9.0+ :
발송 (포스트) 알림 :
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)
또는
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil, userInfo: ["Renish":"Dadhaniya"])
알림 받기 :
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
수신 된 알림에 대한 함수 메소드 핸들러 :
@objc func methodOfReceivedNotification(notification: Notification) {}
스위프트 3.0 및 Xcode 8.0 이상 :
발송 (포스트) 알림 :
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)
알림 받기 :
NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
수신 된 알림에 대한 메소드 핸들러 :
func methodOfReceivedNotification(notification: Notification) {
// Take Action on Notification
}
알림 제거 :
deinit {
NotificationCenter.default.removeObserver(self, name: Notification.Name("NotificationIdentifier"), object: nil)
}
스위프트 2.3 및 Xcode 7 :
발송 (포스트) 알림
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
알림 받기 (받기)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name:"NotificationIdentifier", object: nil)
수신 된 알림에 대한 메소드 핸들러
func methodOfReceivedNotification(notification: NSNotification){
// Take Action on Notification
}
역사적인 Xcode 버전의 경우 …
발송 (포스트) 알림
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
알림 받기 (받기)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOfReceivedNotification:", name:"NotificationIdentifier", object: nil)
알림 제거
NSNotificationCenter.defaultCenter().removeObserver(self, name: "NotificationIdentifier", object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self) // Remove from all notifications being observed
수신 된 알림에 대한 메소드 핸들러
func methodOfReceivedNotification(notification: NSNotification) {
// Take Action on Notification
}
@objc로 클래스 또는 대상 메소드에 주석을 답니다.
@objc private func methodOfReceivedNotification(notification: NSNotification) {
// Take Action on Notification
}
// Or
dynamic private func methodOfReceivedNotification(notification: NSNotification) {
// Take Action on Notification
}
답변
이 작업을 수행하는 좋은 방법은 Objective-C 코드에서 자주 사용되는 방법이 addObserver(forName:object:queue:using:)
아닌 방법 을 사용하는 것 addObserver(_:selector:name:object:)
입니다. 첫 번째 변형의 장점은 @objc
메소드 에서 속성 을 사용할 필요가 없다는 것입니다 .
func batteryLevelChanged(notification: Notification) {
// do something useful with this information
}
let observer = NotificationCenter.default.addObserver(
forName: NSNotification.Name.UIDeviceBatteryLevelDidChange,
object: nil, queue: nil,
using: batteryLevelChanged)
원하는 경우 메소드 대신 클로저를 사용할 수도 있습니다.
let observer = NotificationCenter.default.addObserver(
forName: NSNotification.Name.UIDeviceBatteryLevelDidChange,
object: nil, queue: nil) { _ in print("?") }
반환 된 값을 사용하여 나중에 알림 수신을 중지 할 수 있습니다.
NotificationCenter.default.removeObserver(observer)
이 방법을 사용할 때 또 다른 이점이 있었는데, 이는 컴파일러가 정적으로 확인할 수없는 선택기 문자열을 사용할 필요가 없으므로 메소드의 이름이 바뀌면 깨지기 쉽지 않습니다. 그러나 Swift 2.2 및 나중에 해당 문제를 해결하는 #selector
표현식 이 포함됩니다 .
답변
Xcode 8의 스위프트 3.0
Swift 3.0은 struct
NotificationCenter와 마찬가지로 많은 “문자열 유형”API를 “래퍼 유형”으로 대체했습니다 . 알림은 이제가 struct Notfication.Name
아닌로 식별 됩니다 String
. Swift 3로 마이그레이션 안내서를 참조하십시오. .
이전 사용법 :
// Define identifier
let notificationIdentifier: String = "NotificationIdentifier"
// Register to receive notification
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name: notificationIdentifier, object: nil)
// Post a notification
NSNotificationCenter.defaultCenter().postNotificationName(notificationIdentifier, object: nil)
새로운 Swift 3.0 사용법 :
// Define identifier
let notificationName = Notification.Name("NotificationIdentifier")
// Register to receive notification
NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification), name: notificationName, object: nil)
// Post notification
NotificationCenter.default.post(name: notificationName, object: nil)
모든 시스템 알림 유형은 이제 정적 상수로 정의됩니다 Notification.Name
. 즉 .UIDeviceBatteryLevelDidChange
, .UIApplicationDidFinishLaunching
,.UITextFieldTextDidChange
, 등
Notification.Name
시스템 알림과 일관성을 유지하기 위해 고유 한 사용자 지정 알림으로 확장 할 수 있습니다 .
// Definition:
extension Notification.Name {
static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName")
}
// Usage:
NotificationCenter.default.post(name: .yourCustomNotificationName, object: nil)
답변
-
알림 이름 선언
extension Notification.Name { static let purchaseDidFinish = Notification.Name("purchaseDidFinish") }
-
두 가지 방법으로 관찰자를 추가 할 수 있습니다.
사용
Selector
NotificationCenter.default.addObserver(self, selector: #selector(myFunction), name: .purchaseDidFinish, object: nil) @objc func myFunction(notification: Notification) { print(notification.object ?? "") //myObject print(notification.userInfo ?? "") //[AnyHashable("key"): "Value"] }
또는 사용
block
NotificationCenter.default.addObserver(forName: .purchaseDidFinish, object: nil, queue: nil) { [weak self] (notification) in guard let strongSelf = self else { return } strongSelf.myFunction(notification: notification) } func myFunction(notification: Notification) { print(notification.object ?? "") //myObject print(notification.userInfo ?? "") //[AnyHashable("key"): "Value"] }
-
알림 게시
NotificationCenter.default.post(name: .purchaseDidFinish, object: "myObject", userInfo: ["key": "Value"])
iOS 9 및 OS X 10.11에서. 더 이상 NSNotificationCenter 옵저버가 할당 해제 될 때 자체 등록을 해제 할 필요가 없습니다.더 많은 정보
A의 block
기반 구현을 사용하려는 경우 약한 강한 춤을 할 필요가self
블록 내에서. 더 많은 정보
블록 기반 관찰자는 더 많은 정보를 제거해야합니다.
let center = NSNotificationCenter.defaultCenter()
center.removeObserver(self.localeChangeObserver)
답변
NSNotificationCenter를 사용하여 데이터 전달
swift 3.0에서는 NotificationCentre를 사용하고 swift 2.0에서는 NSNotificationCenter를 사용하여 데이터를 전달할 수도 있습니다.
스위프트 2.0 버전
[NSObject : AnyObject] 유형의 선택적인 사전 인 userInfo를 사용하여 정보를 전달 하시겠습니까?
let imageDataDict:[String: UIImage] = ["image": image]
// Post a notification
NSNotificationCenter.defaultCenter().postNotificationName(notificationName, object: nil, userInfo: imageDataDict)
// Register to receive notification in your class
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.showSpinningWheel(_:)), name: notificationName, object: nil)
// handle notification
func showSpinningWheel(notification: NSNotification) {
if let image = notification.userInfo?["image"] as? UIImage {
// do something with your image
}
}
스위프트 3.0 버전
userInfo는 이제 [AnyHashable : Any]? Swift에서 사전 리터럴로 제공하는 인수로
let imageDataDict:[String: UIImage] = ["image": image]
// post a notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: imageDataDict)
// `default` is now a property, not a method call
// Register to receive notification in your class
NotificationCenter.default.addObserver(self, selector: #selector(self.showSpinningWheel(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)
// handle notification
func showSpinningWheel(_ notification: NSNotification) {
if let image = notification.userInfo?["image"] as? UIImage {
// do something with your image
}
}
NotificationCentre (swift 3.0) 및 NSNotificationCenter (swift 2.0)를 사용한 소스 패스 데이터
답변
에서 스위프트 (5)
ViewControllerB에서 ViewControllerA로 데이터를 수신하려면
ViewControllerA (수신기)
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//MARK: - - - - - Code for Passing Data through Notification Observer - - - - -
// add observer in controller(s) where you want to receive data
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
}
//MARK: - - - - - Method for receiving Data through Post Notificaiton - - - - -
@objc func methodOfReceivedNotification(notification: Notification) {
print("Value of notification : ", notification.object ?? "")
}
}
ViewControllerB (발신자)
import UIKit
class ViewControllerB: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//MARK: - - - - - Set data for Passing Data Post Notification - - - - -
let objToBeSent = "Test Message from Notification"
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)
}
}