web-dev-qa-db-ja.com

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を他のクラスに渡したいです。

121
Jon

「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);
    }
}
225
LearnCocos2D

ソリューションに基づいて、独自のカスタムデータオブジェクト(ここでは質問ごとに「メッセージ」と呼びます)を渡す例を示すと役立つと思います。

クラス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
    }
}
89
David Douglas

Swift 2バージョン

@Johan Karlssonが指摘したように...私はそれを間違っていました。 NSNotificationCenterで情報を送受信する適切な方法を次に示します。

最初に、postNotificationNameの初期化子を確認します。

init(name name: String,
   object object: AnyObject?,
 userInfo userInfo: [NSObject : AnyObject]?)

ソース

userInfo paramを使用して情報を渡します。 [NSObject : AnyObject]タイプは、Objective-Cからのホールドオーバーです。したがって、Swift landで行う必要があるのは、NSObjectから派生したキーとAnyObjectにできる値を持つSwift辞書を渡すことだけです。

その知識があれば、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)
}
24
Dan Beaulieu

スイフト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.key0Notification.Key.key1に置き換えます。

extension Notification {
  enum Key: String {
    case key0
    case key1
  }
}

なぜ私はこれを間違いなくする必要がありますか?コストのかかるタイプミスを回避するには、名前の変更、使用方法の検索などをお楽しみください。

17
frouo