objective-c - notification - observer swift
Cómo pasar un objeto con NSNotificationCenter (4)
Estoy tratando de pasar un objeto de mi delegado de aplicación a un receptor de notificación en otra clase.
Quiero pasar messageTotal
. En este momento tengo:
En el receptor:
- (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];
En la clase que está haciendo la notificación:
[UIApplication sharedApplication].applicationIconBadgeNumber = messageTotal;
[[NSNotificationCenter defaultCenter] postNotificationName:@"eRXReceived" object:self];
Pero quiero pasar el messageTotal
a la otra clase.
Versión Swift 2
Como lo señaló @Johan Karlsson ... lo estaba haciendo mal. Esta es la forma correcta de enviar y recibir información con NSNotificationCenter.
Primero, miramos el inicializador para postNotificationName:
init(name name: String,
object object: AnyObject?,
userInfo userInfo: [NSObject : AnyObject]?)
Pasaremos nuestra información usando el userInfo
. El tipo [NSObject : AnyObject]
es una retención de Objective-C . Entonces, en Swift land, todo lo que tenemos que hacer es pasar en un diccionario Swift que tiene claves que se derivan de NSObject
y valores que pueden ser AnyObject
.
Con ese conocimiento creamos un diccionario que pasaremos al parámetro del object
:
var userInfo = [String:String]()
userInfo["UserName"] = "Dan"
userInfo["Something"] = "Could be any object including a custom Type."
Luego pasamos el diccionario a nuestro parámetro de objeto.
Remitente
NSNotificationCenter.defaultCenter()
.postNotificationName("myCustomId", object: nil, userInfo: userInfo)
Clase de receptor
Primero debemos asegurarnos de que nuestra clase esté observando la notificación
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("btnClicked:"), name: "myCustomId", object: nil)
}
Entonces podemos recibir nuestro diccionario:
func btnClicked(notification: NSNotification) {
let userInfo : [String:String!] = notification.userInfo as! [String:String!]
let name = userInfo["UserName"]
print(name)
}
Swift 4
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"]
}
Bonificación (¡definitivamente debes hacerlo!):
Reemplazar Notification.Name("SomeNotificationName")
con .someNotificationName
:
extension Notification.Name {
static let someNotificationName = Notification.Name("SomeNotificationName")
}
Reemplace "key0"
y "key1"
con Notification.Key.key0
y Notification.Key.key1
:
extension Notification.Key {
static let key0 = "key0"
static let key1 = "key1"
}
¿Por qué debería definitivamente hacer esto? Para evitar costosos errores tipográficos, disfruta de cambiar el nombre, disfrutar el uso, etc ...
Basándome en la solución provista, pensé que podría ser útil mostrar un ejemplo al pasar su propio objeto de datos personalizado (al que he hecho referencia aquí como ''mensaje'' según la pregunta).
Clase A (remitente):
YourDataObject *message = [[YourDataObject alloc] init];
// set your message properties
NSDictionary *dict = [NSDictionary dictionaryWithObject:message forKey:@"message"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"NotificationMessageEvent" object:nil userInfo:dict];
Clase B (receptor):
- (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
}
}
Deberá usar la variante "userInfo" y pasar un objeto NSDictionary que contenga el mensaje TotalTotal:
NSDictionary* userInfo = @{@"total": @(messageTotal)};
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"eRXReceived" object:self userInfo:userInfo];
En el extremo receptor puede acceder al diccionario userInfo de la siguiente manera:
-(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);
}
}