내 앱 대리자에서 다른 클래스의 알림 수신자로 객체를 전달하려고합니다.
integer 전달하고 싶습니다 messageTotal
. 지금 나는 가지고 있습니다 :
수신기에서 :
- (void) receiveTestNotification:(NSNotification *) notification
{
if ([[notification name] isEqualToString:@"TestNotification"])
NSLog (@"Successfully received the test notification!");
}
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissSheet) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveTestNotification:) name:@"eRXReceived" object:nil];
알림을 수행하는 클래스에서 :
[UIApplication sharedApplication].applicationIconBadgeNumber = messageTotal;
[[NSNotificationCenter defaultCenter] postNotificationName:@"eRXReceived" object:self];
그러나 객체 messageTotal
를 다른 클래스 에 전달하고 싶습니다 .
답변
“userInfo”변형을 사용해야하고 messageTotal 정수를 포함하는 NSDictionary 객체를 전달해야합니다.
NSDictionary* userInfo = @{@"total": @(messageTotal)};
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"eRXReceived" object:self userInfo:userInfo];
수신 측에서 다음과 같이 userInfo 사전에 액세스 할 수 있습니다.
-(void) receiveTestNotification:(NSNotification*)notification
{
if ([notification.name isEqualToString:@"TestNotification"])
{
NSDictionary* userInfo = notification.userInfo;
NSNumber* total = (NSNumber*)userInfo[@"total"];
NSLog (@"Successfully received test notification! %i", total.intValue);
}
}
답변
제공된 솔루션을 기반으로 사용자 정의 데이터 객체 (여기서는 질문 당 ‘메시지’로 참조)를 전달하는 예제를 보여주는 것이 도움이 될 것이라고 생각했습니다.
클래스 A (발신자) :
YourDataObject *message = [[YourDataObject alloc] init];
// set your message properties
NSDictionary *dict = [NSDictionary dictionaryWithObject:message forKey:@"message"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"NotificationMessageEvent" object:nil userInfo:dict];
클래스 B (수신자) :
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(triggerAction:) name:@"NotificationMessageEvent" object:nil];
}
#pragma mark - Notification
-(void) triggerAction:(NSNotification *) notification
{
NSDictionary *dict = notification.userInfo;
YourDataObject *message = [dict valueForKey:@"message"];
if (message != nil) {
// do stuff here with your message data
}
}
답변
스위프트 2 버전
@Johan Karlsson이 지적했듯이 … 잘못하고있었습니다. NSNotificationCenter와 정보를주고받는 올바른 방법은 다음과 같습니다.
먼저 postNotificationName의 초기화 프로그램을 살펴 봅니다.
init(name name: String,
object object: AnyObject?,
userInfo userInfo: [NSObject : AnyObject]?)
우리는 userInfo
매개 변수를 사용하여 정보를 전달할 것 입니다. 이 [NSObject : AnyObject]
유형은 Objective-C 의 보류 입니다. 따라서 Swift 토지에서 우리가해야 할 일은 파생 된 키 NSObject
와 가능한 값을 가진 Swift 사전을 전달 하는 것입니다.AnyObject
입니다.
그 지식으로 우리는 object
매개 변수에 전달할 사전을 만듭니다 .
var userInfo = [String:String]()
userInfo["UserName"] = "Dan"
userInfo["Something"] = "Could be any object including a custom Type."
그런 다음 사전을 객체 매개 변수에 전달합니다.
송신기
NSNotificationCenter.defaultCenter()
.postNotificationName("myCustomId", object: nil, userInfo: userInfo)
리시버 클래스
먼저 우리는 클래스가 알림을 관찰하고 있는지 확인해야합니다
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("btnClicked:"), name: "myCustomId", object: nil)
}
그런 다음 사전을받을 수 있습니다.
func btnClicked(notification: NSNotification) {
let userInfo : [String:String!] = notification.userInfo as! [String:String!]
let name = userInfo["UserName"]
print(name)
}
답변
스위프트 5
func post() {
NotificationCenter.default.post(name: Notification.Name("SomeNotificationName"),
object: nil,
userInfo:["key0": "value", "key1": 1234])
}
func addObservers() {
NotificationCenter.default.addObserver(self,
selector: #selector(someMethod),
name: Notification.Name("SomeNotificationName"),
object: nil)
}
@objc func someMethod(_ notification: Notification) {
let info0 = notification.userInfo?["key0"]
let info1 = notification.userInfo?["key1"]
}
보너스 (확실히해야합니다!) :
교체 Notification.Name("SomeNotificationName")
로 .someNotificationName
:
extension Notification.Name {
static let someNotificationName = Notification.Name("SomeNotificationName")
}
교체 "key0"
와 "key1"
함께 Notification.Key.key0
와 Notification.Key.key1
:
extension Notification {
enum Key: String {
case key0
case key1
}
}
왜 내가 이것을 분명히해야합니까? 값 비싼 오타를 피하려면 이름 바꾸기를 즐기고 사용법 찾기 등을 즐기십시오.
답변
스위프트 5.1 커스텀 객체 / 타입
// MARK: - NotificationName
// Extending notification name to avoid string errors.
extension Notification.Name {
static let yourNotificationName = Notification.Name("yourNotificationName")
}
// MARK: - CustomObject
class YourCustomObject {
// Any stuffs you would like to set in your custom object as always.
init() {}
}
// MARK: - Notification Sender Class
class NotificatioSenderClass {
// Just grab the content of this function and put it to your function responsible for triggering a notification.
func postNotification(){
// Note: - This is the important part pass your object instance as object parameter.
let yourObjectInstance = YourCustomObject()
NotificationCenter.default.post(name: .yourNotificationName, object: yourObjectInstance)
}
}
// MARK: -Notification Receiver class
class NotificationReceiverClass: UIViewController {
// MARK: - ViewController Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// Register your notification listener
NotificationCenter.default.addObserver(self, selector: #selector(didReceiveNotificationWithCustomObject), name: .yourNotificationName, object: nil)
}
// MARK: - Helpers
@objc private func didReceiveNotificationWithCustomObject(notification: Notification){
// Important: - Grab your custom object here by casting the notification object.
guard let yourPassedObject = notification.object as? YourCustomObject else {return}
// That's it now you can use your custom object
//
//
}
// MARK: - Deinit
deinit {
// Save your memory by releasing notification listener
NotificationCenter.default.removeObserver(self, name: .yourNotificationName, object: nil)
}
}