Swift에서 옵저버를 기본 알림 센터에 어떻게 추가합니까? 배터리 잔량이 변경되면 알림을 보내는이 코드 줄을 이식하려고합니다.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
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
}
UIDeviceBatteryLevelDidChangeNotification
따옴표가 없습니까? 문자열 타입입니다.
@objc
.
발송 (포스트) 알림 :
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) {}
발송 (포스트) 알림 :
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)
}
발송 (포스트) 알림
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
}
@objc
.
methodOFReceivedNotication
dynamic
NSObject의 서브 클래스로 주석을 달거나 구성원 이어야합니다 .
object 0x7fd68852d710 of class 'TestNotifications.MyObject' does not implement methodSignatureForSelector: -- trouble ahead
.Unrecognized selector -[TestNotifications.MyObject methodOFReceivedNotication:]
이 작업을 수행하는 좋은 방법은 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
표현식 이 포함됩니다 .
addObserver(_:selector:name:object:)
등록 해제 방법과 는 상당히 다릅니다 . 당신은에 의해 반환 된 개체를 유지해야 addObserverForName(_:object:queue:usingBlock:)
하고에 전달removeObserver:
addObserverForName(_:object:queue:usingBlock:)
.
UIViewController
및 참조 self
그 폐쇄, 당신은 사용할 필요 [weak self]
하거나 참조주기 및 메모리 누수를해야합니다.
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)
}
}
@objc로 주석을 달지 않고 선택기를 성공적으로 사용하기 위해 다음 중 하나를 수행 할 수 있습니다 .
NSNotificationCenter.defaultCenter().addObserver(self,
selector:"batteryLevelChanged:" as Selector,
name:"UIDeviceBatteryLevelDidChangeNotification",
object:nil)
또는
let notificationSelector: Selector = "batteryLevelChanged:"
NSNotificationCenter.defaultCenter().addObserver(self,
selector: notificationSelector,
name:"UIDeviceBatteryLevelDidChangeNotification",
object:nil)
내 xcrun 버전은 Swift 1.2를 보여 주며 Xcode 6.4 및 Xcode 7 베타 2에서 작동합니다 (Swift 2.0을 사용한다고 생각했습니다).
$xcrun swift --version
Apple Swift version 1.2 (swiftlang-602.0.53.1 clang-602.0.53)
@objc
옵저버 클래스가에서 상속받은 경우 주석을 달지 않아도됩니다 NSObject
.
String
에 Selector
중. :)
@objc
아닌 NSObject
클래스 의 메서드에서 주석을 제거하고 선택기 이름에 as Selector
캐스팅을 추가 String
했으며 알림이 실행될 때 앱이 중단됩니다. 내 Swift 버전은 귀하의 버전과 동일합니다.
@objc
주석이 당신을 위해 효과가 있고이 방법으로는 효과가 없다면, 계속 주석을 달아주세요!
Swift 3, Xcode 8.2에서 : 배터리 상태 확인
//Add observer
NotificationCenter.default.addObserver(self, selector: #selector(batteryStateDidChange), name: NSNotification.Name.UIDeviceBatteryStateDidChange, object: nil)
//Fired when battery level changes
func batteryStateDidChange(notification: NSNotification){
//perform manipulation here
}
NSNotificationCenter , iOS 11 용 Swift 4.0 에서 옵저버 구문 추가
NotificationCenter.default.addObserver(self, selector: #selector(keyboardShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
이것은 keyboardWillShow 알림 이름 유형입니다. 사용 가능한 옵션에서 다른 유형을 선택할 수 있습니다
선택기는 @objc func 유형이며 키보드 표시 방법을 처리합니다 (이것은 사용자 기능입니다)
#selector
주석을 달아야 함을 의미합니다 @objc
. 예를 들어 @objc func keyboardShow() { ... }
, Swift 4에서 잠시 동안 나를 던졌습니다!
스위프트 5 및 Xcode 10.2 :
NotificationCenter.default.addObserver(
self,
selector: #selector(batteryLevelDidChangeNotification),
name: UIDevice.batteryLevelDidChangeNotification,
object: nil)
스위프트 5 알림 관찰자
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(batteryLevelChanged), name: UIDevice.batteryLevelDidChangeNotification, object: nil)
}
@objc func batteryLevelChanged(notification : NSNotification){
//do here code
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self, name: UIDevice.batteryLevelDidChangeNotification, object: nil)
}