Как передать объект с помощью NSNotificationCenter
Я пытаюсь передать объект из моего делегата приложения в приемник уведомлений в другом классе.
Я хочу передать целое число 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
другому классу.
Ответы
Ответ 1
Вам придется использовать вариант "userInfo" и передать объект NSDictionary, содержащий целое число messageTotal:
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);
}
}
Ответ 2
Основываясь на предоставленном решении, я подумал, что было бы полезно показать пример, передающий свой собственный объект данных (который я назвал здесь как "сообщение" в соответствии с вопросом).
Класс 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
}
}
Ответ 3
версия Swift 2
Как сказал @Johan Karlsson... Я делал это неправильно. Здесь правильный способ отправки и получения информации с помощью NSNotificationCenter.
Сначала мы рассмотрим инициализатор для postNotificationName:
init(name name: String,
object object: AnyObject?,
userInfo userInfo: [NSObject : AnyObject]?)
источник
Мы передадим нашу информацию с помощью параметра userInfo
. Тип [NSObject : AnyObject]
является удержанием от Objective-C. Итак, в Swift-стране все, что нам нужно сделать, это передать словарь Swift с ключами, которые получены из NSObject
и значениями, которые могут быть AnyObject
.
С помощью этого знания мы создаем словарь, который мы перейдем в параметр object
:
var userInfo = [String:String]()
userInfo["UserName"] = "Dan"
userInfo["Something"] = "Could be any object including a custom Type."
Затем мы передаем словарь в наш объектный параметр.
Sender
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)
}
Ответ 4
Swift 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
}
}
Почему я должен определенно делать это? Чтобы избежать дорогостоящих ошибок при опечатке, переименовывайтесь, пользуйтесь поиском и т.д.