Próbuję przekazać obiekt z delegata mojej aplikacji do odbiorcy powiadomień w innej klasie.
Chcę przekazać liczbę całkowitą messageTotal
. W tej chwili mam:
W odbiorniku:
- (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];
W klasie wykonującej powiadomienie:
[UIApplication sharedApplication].applicationIconBadgeNumber = messageTotal;
[[NSNotificationCenter defaultCenter] postNotificationName:@"eRXReceived" object:self];
Ale chcę przekazać obiekt messageTotal
drugiej klasie.
Odpowiedzi:
Będziesz musiał użyć wariantu „userInfo” i przekazać obiekt NSDictionary, który zawiera wartość całkowitą messageTotal:
NSDictionary* userInfo = @{@"total": @(messageTotal)}; NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; [nc postNotificationName:@"eRXReceived" object:self userInfo:userInfo];
Po stronie odbierającej dostęp do słownika userInfo można uzyskać w następujący sposób:
-(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); } }
źródło
messageTotal
odznakę na UIButton, czy wiesz, jak mogę odświeżyć przycisk za pomocą nowej liczby odznak? Kod do wyświetlenia obrazuviewDidLoad
toUIBarButtonItem *eRXButton = [BarButtonBadge barButtonWithImage:buttonImage badgeString:@"1" atRight:NO toTarget:self action:@selector(eRXButtonPressed)];
Opierając się na dostarczonym rozwiązaniu, pomyślałem, że pomocne może być pokazanie przykładu przekazywania własnego niestandardowego obiektu danych (do którego odnosiłem się tutaj jako „wiadomość” zgodnie z pytaniem).
Klasa A (nadawca):
YourDataObject *message = [[YourDataObject alloc] init]; // set your message properties NSDictionary *dict = [NSDictionary dictionaryWithObject:message forKey:@"message"]; [[NSNotificationCenter defaultCenter] postNotificationName:@"NotificationMessageEvent" object:nil userInfo:dict];
Klasa B (odbiornik):
- (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 } }
źródło
object
param siępostNotificationName
powinno czyli ten, który wysłania tego powiadomienia.userInfo
parametru, a zaakceptowana odpowiedź powyżej została zmieniona, aby to pokazać.userInfo
słownika jako sposobu przekazywania danych obiektu.Jak zauważył @Johan Karlsson ... Zrobiłem to źle. Oto właściwy sposób wysyłania i otrzymywania informacji za pomocą NSNotificationCenter.
Najpierw przyjrzymy się inicjalizatorowi postNotificationName:
init(name name: String, object object: AnyObject?, userInfo userInfo: [NSObject : AnyObject]?)
źródło
Będziemy przekazywać nasze informacje za pomocą
userInfo
parametru.[NSObject : AnyObject]
Typ to hold-over z Objective-C . Tak więc w krainie Swift wszystko, co musimy zrobić, to przekazać słownik języka Swift, który ma klucze, z których pochodząNSObject
i wartości, które mogą byćAnyObject
.Mając tę wiedzę tworzymy słownik, który przekażemy do
object
parametru:var userInfo = [String:String]() userInfo["UserName"] = "Dan" userInfo["Something"] = "Could be any object including a custom Type."
Następnie przekazujemy słownik do naszego parametru obiektu.
Nadawca
NSNotificationCenter.defaultCenter() .postNotificationName("myCustomId", object: nil, userInfo: userInfo)
Klasa odbiornika
Najpierw musimy się upewnić, że nasza klasa obserwuje powiadomienie
override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("btnClicked:"), name: "myCustomId", object: nil) }
Wtedy możemy otrzymać nasz słownik:
func btnClicked(notification: NSNotification) { let userInfo : [String:String!] = notification.userInfo as! [String:String!] let name = userInfo["UserName"] print(name) }
źródło
Szybki 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"] }
Bonus (który zdecydowanie powinieneś zrobić!):
Wymienić
Notification.Name("SomeNotificationName")
z.someNotificationName
:extension Notification.Name { static let someNotificationName = Notification.Name("SomeNotificationName") }
Wymień
"key0"
i"key1"
zNotification.Key.key0
aNotification.Key.key1
:extension Notification { enum Key: String { case key0 case key1 } }
Dlaczego zdecydowanie powinienem to zrobić? Aby uniknąć kosztownych błędów literowych, ciesz się zmianą nazwy, korzystaj z wyszukiwania itp.
źródło
'Key' is not a member type of 'Notification'
. Zobacz tutaj: https://ibb.co/hDQYbd2Key
struktura została usunięta od tego czasu. Aktualizuję odpowiedźSwift 5.1 Custom Object / Type
// 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) } }
źródło