メッセージの送信

トピックの作成が完了したら、いよいよプッシュメッセージの送信です。トピックにメッセージを送信すると、このトピックを購読している全てのユーザーに対してメッセージがプッシュされます。

アプリケーションスコープのトピックへの送信

アプリケーションスコープのトピックには、アプリ開発者のみが開発者ポータルを使ってメッセージを送信できます。

送信方法は ユーザープッシュ通知の送信 をご覧ください。

グループスコープ/ユーザースコープのトピックへの送信

グループスコープのトピックまたはユーザースコープのトピックには、モバイルアプリからメッセージを送信できます。

メッセージの送信

グループスコープのトピックには、任意のグループメンバーがメッセージを送ることができます。

以下に、メッセージ送信を行うコード例を挙げます。このサンプルコードでは、プッシュメッセージを FCM、APNs、および MQTT のプッシュ通知ネットワークに送信します。

Swift:

  • // Instantiate a group.
    let group = KiiGroup(uri: groupUri)
    
    do{
      // Refresh the group.
      try group.refreshSynchronous()
    } catch let error as NSError {
      // Handle the error.
      return
    }
    
    // Instantiate a topic in the group scope.
    let topicName = "GroupTopic"
    let topic = group.topic(withName: topicName)
    
    // Create a container of APNs-specific data.
    let apnsFields = KiiAPNSFields.create()
    
    // Make the notification silent.
    apnsFields.contentAvailable = 1
    
    // This sample code sends a silent notification,
    // so the title, subtitle, and body keys are not set.
    // apnsFields.alertTitle = "New message"
    // apnsFields.alertSubtitle = "Message from Alice"
    // apnsFields.alertBody = "It's been a while..."
    
    // Define the category.
    // apnsFields.category = "MESSAGE_CATEGORY"
    
    // Let the implemented Notification Service Extension or
    // Notification Content Extension process the message.
    // apnsFields.mutableContent = 1
    
    // Create push message data.
    var data = [AnyHashable: Any]()
    data["str"] = "str"
    data["int"] = NSNumber(value: 1 as Int)
    data["bool"] = NSNumber(value: false as Bool)
    data["double"] = NSNumber(value: 1.12 as Double)
    
    // Create a push message.
    let message = KiiPushMessage.composeMessage(with: data)
    message.apnsFields = apnsFields
    
    do{
      // Send the push message.
      try topic.sendMessageSynchronous(message)
    } catch let error as NSError {
      // Handle the error.
      return
    }
  • // Instantiate a group.
    let group = KiiGroup(uri: groupUri)
    
    // Refresh the group.
    group.refresh { (group : KiiGroup?, error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
    
      // Instantiate a topic in the group scope.
      let topicName = "GroupTopic"
      let topic = group!.topic(withName: topicName)
    
      // Create a container of APNs-specific data.
      let apnsFields = KiiAPNSFields.create()
    
      // Make the notification silent.
      apnsFields.contentAvailable = 1
    
      // This sample code sends a silent notification,
      // so the title, subtitle, and body keys are not set.
      // apnsFields.alertTitle = "New message"
      // apnsFields.alertSubtitle = "Message from Alice"
      // apnsFields.alertBody = "It's been a while..."
    
      // Define the category.
      // apnsFields.category = "MESSAGE_CATEGORY"
    
      // Let the implemented Notification Service Extension or
      // Notification Content Extension process the message.
      // apnsFields.mutableContent = 1
    
      // Create push message data.
      var data = [AnyHashable: Any]()
      data["str"] = "str"
      data["int"] = NSNumber(value: 1 as Int)
      data["bool"] = NSNumber(value: false as Bool)
      data["double"] = NSNumber(value: 1.12 as Double)
    
      // Create a push message.
      let message = KiiPushMessage.composeMessage(with: data)
      message.apnsFields = apnsFields
    
      // Send the push message.
      topic.send(message, with: { (topic , error : Error?) -> Void in
        if error != nil {
          // Handle the error.
          return
        }
      })
    }

Objective-C:

  • NSError *error = nil;
    
    // Instantiate a group.
    KiiGroup *group = [KiiGroup groupWithURI:groupUri];
    
    // Refresh the group.
    [group refreshSynchronous:&error];
    if (error != nil) {
      // Handle the error.
      return;
    }
    
    // Instantiate a topic in the group scope.
    NSString *topicname = @"GroupTopic";
    KiiTopic *topic = [group topicWithName:topicname];
    
    // Create a container of APNs-specific data.
    KiiAPNSFields *apnsFields = [KiiAPNSFields createFields];
    
    // Make the notification silent.
    [apnsFields setContentAvailable:@1];
    
    // This sample code sends a silent notification,
    // so the title, subtitle, and body keys are not set.
    // [apnsFields setAlertTitle:@"New message"];
    // [apnsFields setAlertSubtitle:@"Message from Alice"];
    // [apnsFields setAlertBody:@"It's been a while..."];
    
    // Define the category.
    // [apnsFields setCategory:@"MESSAGE_CATEGORY"];
    
    // Let the implemented Notification Service Extension or
    // Notification Content Extension process the message.
    // [apnsFields setMutableContent:@1];
    
    // Create push message data.
    NSMutableDictionary *data = [NSMutableDictionary dictionary];
    data[@"str"]=@"str";
    data[@"int"]=[NSNumber numberWithInt:1];
    data[@"bool"]=@YES;
    data[@"double"]=[NSNumber numberWithDouble:1.12];
    
    // Create a push message.
    KiiPushMessage *message = [KiiPushMessage composeMessageWithData:data];
    message.apnsFields = apnsFields;
    
    // Send the push message.
    [topic sendMessageSynchronous:message
                        withError:&error];
    
    if (error != nil) {
      // Handle the error.
      return;
    }
  • // Instantiate a group.
    KiiGroup *group = [KiiGroup groupWithURI:groupUri];
    
    // Refresh the group.
    [group refreshWithBlock:^(KiiGroup *group, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
    
      // Instantiate a topic in the group scope.
      NSString *topicname = @"GroupTopic";
      KiiTopic *topic = [group topicWithName:topicname];
    
      // Create a container of APNs-specific data.
      KiiAPNSFields *apnsFields = [KiiAPNSFields createFields];
    
      // Make the notification silent.
      [apnsFields setContentAvailable:@1];
    
      // This sample code sends a silent notification,
      // so the title, subtitle, and body keys are not set.
      // [apnsFields setAlertTitle:@"New message"];
      // [apnsFields setAlertSubtitle:@"Message from Alice"];
      // [apnsFields setAlertBody:@"It's been a while..."];
    
      // Define the category.
      // [apnsFields setCategory:@"MESSAGE_CATEGORY"];
    
      // Let the implemented Notification Service Extension or
      // Notification Content Extension process the message.
      // [apnsFields setMutableContent:@1];
    
      // Create push message data.
      NSMutableDictionary *data = [NSMutableDictionary dictionary];
      data[@"str"]=@"str";
      data[@"int"]=[NSNumber numberWithInt:1];
      data[@"bool"]=@YES;
      data[@"double"]=[NSNumber numberWithDouble:1.12];
    
      // Create a push message.
      KiiPushMessage *message = [KiiPushMessage composeMessageWithData:data];
      message.apnsFields = apnsFields;
    
      // Send the push message.
      [topic sendMessage:message
             withBlock:^(KiiTopic *topic, NSError *error) {
        if (error != nil) {
          // Handle the error.
          return;
        }
      }];
    }];

ここでは、以下の処理を実行しています。

  • createFields メソッドを実行し、APNs のメッセージフィールドのインスタンスを作成します。
  • サイレント通知 を利用する場合は contentAvailable プロパティに 1 を設定します。
    サイレント通知を利用しない場合は、必要に応じて alertTitle プロパティ、alertSubtitle プロパティ、alertBody プロパティを使って、タイトル、サブタイトル、本文を設定します。
  • (iOS 8 よりサポートされた)通知カテゴリーを使用する場合は、あらかじめアプリに登録していおいたカテゴリー ID を category プロパティに設定します。カテゴリー ID の登録方法の詳細は アクション付きプッシュ通知の初期化 を参照してください。
  • (iOS 10 よりサポートされた)リッチ通知を使って、画像付きプッシュ通知やカスタム UI の機能を利用する場合は、mutableContent プロパティに 1 を設定します。この場合は、受信したプッシュメッセージを適切に処理できるように、Notification Content Extension や Notification Service Extension を実装します。
  • composeMessageWithData: メソッドを実行してプッシュメッセージを作成し、メッセージの本体を割り当てます。
  • sendMessageSynchronous:withError: メソッドまたは sendMessage:withBlock: メソッドを実行し、トピックにプッシュメッセージを送信します。

ユーザースコープのトピックには、このユーザーまたはトピックの所有者のみがメッセージを送信できます。

なお、ここでは refresh(_:) メソッドを実行していますが、group をプッシュメッセージの送信だけに使用する場合は、実行を省略することもできます。

以下に、メッセージ送信を行うコード例を挙げます。このサンプルコードでは、プッシュメッセージを APNs にのみ送信します。

Swift:

  • // Instantiate a topic in the user scope.
    let user = KiiUser.current()!
    let topicName = "MyToDO"
    let topic = user.topic(withName: topicName)
    
    // Create a container of APNs-specific data.
    let apnsFields = KiiAPNSFields.create()
    
    // Create APNs-specific data.
    var dictionary = [AnyHashable: Any]()
    dictionary["item"] = "Do Something"
    dictionary["Done"] = NSNumber(value: 1 as Int32)
    apnsFields.setSpecificData(dictionary)
    
    // Make the notification silent.
    apnsFields.contentAvailable = 1
    
    // This sample code sends a silent notification,
    // so the body key is not set.
    // apnsFields.alertBody = "Show Message"
    
    // Create a push message.
    let message = KiiPushMessage.composeMessage(with:nil)
    
    // Disable FCM and MQTT so that the message will not be sent to devices using FCM or MQTT.
    message.setGCMEnabled(false)
    message.setMQTTEnabled(false)
    message.apnsFields = apnsFields
    
    do{
      // Send the push message.
      try topic.sendMessageSynchronous(message)
    } catch let error as NSError {
      // Handle the error.
      return
    }
  • // Instantiate a topic in the user scope.
    let user = KiiUser.current()!
    let topicName = "MyToDO"
    let topic = user.topic(withName: topicName)
    
    // Create a container of APNs-specific data.
    let apnsFields = KiiAPNSFields.create()
    
    // Create APNs-specific data.
    var dictionary = [AnyHashable: Any]()
    dictionary["item"] = "Do Something"
    dictionary["Done"] = NSNumber(value: 1 as Int32)
    apnsFields.setSpecificData(dictionary)
    
    // Make the notification silent.
    apnsFields.contentAvailable = 1
    
    // This sample code sends a silent notification,
    // so the body key is not set.
    // apnsFields.alertBody = "Show Message"
    
    // Create a push message.
    let message = KiiPushMessage.composeMessage(with:nil)
    
    // Disable FCM and MQTT so that the message will not be sent to devices using FCM or MQTT.
    message.setGCMEnabled(false)
    message.setMQTTEnabled(false)
    message.apnsFields = apnsFields
    
    // Send the push message.
    topic.send(message, with: { (topic , error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
    })

Objective-C:

  • NSError *error = nil;
    
    // Instantiate a topic in the user scope.
    KiiUser* user = [KiiUser currentUser];
    NSString *topicname = @"MyTODO";
    KiiTopic *topic = [user topicWithName:topicname];
    
    // Create a container of APNs-specific data.
    KiiAPNSFields *apnsFields = [KiiAPNSFields createFields];
    
    // Create APNs-specific data.
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
    [dictionary setObject:@"Do Something"
                   forKey:@"Item"];
    [dictionary setObject:[NSNumber numberWithInt:1]
                   forKey:@"Done"];
    [apnsFields setSpecificData:dictionary];
    
    // Make the notification silent.
    [apnsFields setContentAvailable:@1];
    
    // This sample code sends a silent notification,
    // so the body key is not set.
    // [apnsFields setAlertBody:@"Show message"];
    
    // Create a push message.
    KiiPushMessage *message = [KiiPushMessage composeMessageWithData:nil];
    
    // Disable FCM and MQTT so that the message will not be sent to devices using FCM or MQTT.
    [message setGCMEnabled:NO];
    [message setMQTTEnabled:NO];
    message.apnsFields = apnsFields;
    
    // Send the push message.
    [topic sendMessageSynchronous:message
                        withError:&error];
    if (error != nil) {
      // Handle the error.
      return;
    }
  • // Instantiate a topic in the user scope.
    KiiUser* user = [KiiUser currentUser];
    NSString *topicname = @"MyTODO";
    KiiTopic *topic = [user topicWithName:topicname];
    
    // Create a container of APNs-specific data.
    KiiAPNSFields *apnsFields = [KiiAPNSFields createFields];
    
    // Create APNs-specific data.
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
    [dictionary setObject:@"Do Something"
                   forKey:@"Item"];
    [dictionary setObject:[NSNumber numberWithInt:1]
                   forKey:@"Done"];
    [apnsFields setSpecificData:dictionary];
    
    // Make the notification silent.
    [apnsFields setContentAvailable:@1];
    
    // This sample code sends a silent notification,
    // so the body key is not set.
    // [apnsFields setAlertBody:@"Show message"];
    
    // Create a push message.
    KiiPushMessage *message = [KiiPushMessage composeMessageWithData:nil];
    
    // Disable FCM and MQTT so that the message will not be sent to devices using FCM or MQTT.
    [message setGCMEnabled:NO];
    [message setMQTTEnabled:NO];
    message.apnsFields = apnsFields;
    
    // Send the push message.
    [topic sendMessage:message
             withBlock:^(KiiTopic *topic, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
    }];

ここでは以下の処理をしています。

  • createFields メソッドを実行し、APNs メッセージフィールドのインスタンスを作成します。
  • setSpecificData: メソッドを実行し、カスタムフィールドの値をセットします。
  • サイレント通知 を利用する場合は setContentAvailable: メソッドでフラグを立てます。
    サイレント通知を利用しない場合は、必要に応じて setAlertBody: メソッドを実行し、APNs メッセージに APNs alert プロパティを設定します。
  • composeMessageWithData: メソッドを実行し、プッシュメッセージを作成します。setGCMEnabled メソッドおよび setMQTTEnabled メソッドの引数に false を設定し、プッシュメッセージの送信先を APNs のみに制限します。APNs へのメッセージ送信を抑制するには、setAPNSEnabled メソッドを使用します。
  • sendMessageSynchronous:withError: メソッドまたは sendMessage:withBlock: メソッドを実行し、トピックにプッシュメッセージを送信します。

APNs のペイロードを節約する

FCM のペイロード上限は 4 KB(4096 バイト)です。一方、APNs のペイロード上限は 2 KB(2048 バイト)と限られているため、特に長いメッセージを送る際に問題となることがあります。

Kii Cloud は、デフォルトでは指定されたメッセージ内容に加え、いくつかの既定値をプッシュメッセージとして送信します。一例として、以下のように APNs の Body に "short msg only!" を指定したケースを想定します。

Swift:

  • // Create APNs-specific data.
    let apnsFields = KiiAPNSFields.create()
    apnsFields.alertBody = "short message only"
    
    // Create a push message.
    let message = KiiPushMessage.composeMessage(withData:nil)
    message.apnsFields = apnsFields
    message.setGCMEnabled(false)
    message.setMQTTEnabled(false)
    
    do{
      // Send the push message.
      try topic.sendMessageSynchronous(message)
    } catch let error as NSError {
      // Handle the error.
      return
    }
  • // Create APNs-specific data.
    let apnsFields = KiiAPNSFields.create()
    apnsFields.alertBody = "short message only"
    
    // Create a push message.
    let message = KiiPushMessage.composeMessage(withData:nil)
    message.apnsFields = apnsFields
    message.setGCMEnabled(false)
    message.setMQTTEnabled(false)
    
    // Send the push message.
    topic.send(message, with: { (topic , error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
    })

Objective-C:

  • NSError *error = nil;
    
    // Create APNs-specific data.
    KiiAPNSFields *apnsFields = [KiiAPNSFields createFields];
    [apnsFields setAlertBody:@"short msg only!"];
    
    // Create a push message.
    KiiPushMessage *pushMessage = [KiiPushMessage composeMessageWithData:nil];
    pushMessage.apnsFields = apnsFields
    
    // Send the push message.
    [topic sendMessageSynchronous:pushMessage
                        withError:&error];
    if (error != nil) {
      // Handle the error.
      return;
    }
  • // Create APNs-specific data.
    KiiAPNSFields *apnsFields = [KiiAPNSFields createFields];
    [apnsFields setAlertBody:@"short msg only!"];
    
    // Create a push message.
    KiiPushMessage *pushMessage = [KiiPushMessage composeMessageWithData:nil];
    pushMessage.apnsFields = apnsFields
    [pushMessage setGCMEnabled:NO];
    [pushMessage setMQTTEnabled:NO];
    
    // Send the push message.
    [topic sendMessage:pushMessage
             withBlock:^(KiiTopic *topic, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
    }];

この結果、送信されるプッシュメッセージは以下のようなものになります。指定した "short msg only!" だけではなく、いくつかデフォルトキーが追加されていることが分かります。

{
  aps = {
    alert = {
      body = "short msg only!";
    };
  };
  s = "cf6de5b5-8927-48a4-a410-xxxxxxxxxxxx";
  sa = 9a2385ce;
  st = "APP_AND_USER";
  su = "e26ad504-8100-4056-b3d3-xxxxxxxxxxxx";
  to = "MyTopic";
  w = 1373623307000;
}

デフォルトでメッセージに含まれるキーの詳細は以下のとおりです。

  • s:プッシュメッセージ送信者の UserID
  • sa:プッシュメッセージを送信したアプリの AppID
  • s:プッシュメッセージが送信されたトピックのスコープ
    • アプリケーションスコープの場合は "APP"
    • グループスコープの場合は "APP_AND_GROUP"
    • ユーザースコープの場合は "APP_AND_USER"
  • sg:プッシュメッセージが送信されたトピックが属するグループの GroupID(グループスコープのトピックの場合のみ)
  • su:プッシュメッセージが送信されたトピックのオーナーの UserID(ユーザースコープのトピックの場合のみ)
  • to:プッシュメッセージが送信されたトピックの TopicID
  • w:プッシュメッセージ送信時間(UNIX 時間、ミリ秒、UTC)

長いメッセージを送信する場合は、これらのデフォルトキーを抑制することにより使用可能なペイロードを増やすことができます。以下に、デフォルトキーを抑制してプッシュメッセージを送信する例を挙げます。

Swift:

  • // Create APNs-specific data.
    let apnsFields = KiiAPNSFields.create()
    apnsFields.alertBody = "Looooooooooooooooooong Message!!"
    
    // Create a push message with the default keys suppressed.
    let message = KiiPushMessage.composeMessage(withData:nil)
    message.apnsFields = apnsFields
    message.sendSender = NSNumber(value: false as Bool)
    message.sendWhen = NSNumber(value: false as Bool)
    message.sendTopicID = NSNumber(value: false as Bool)
    message.sendObjectScope = NSNumber(value: false as Bool)
    
    do{
      // Send the push message.
      try topic.sendMessageSynchronous(message)
    } catch let error as NSError {
      // Handle the error.
      return
    }
  • // Create APNs-specific data.
    let apnsFields = KiiAPNSFields.create()
    apnsFields.alertBody = "Looooooooooooooooooong Message!!"
    
    // Create a push message with the default keys suppressed.
    let message = KiiPushMessage.composeMessage(withData:nil)
    message.apnsFields = apnsFields
    message.sendSender = NSNumber(value: false as Bool)
    message.sendWhen = NSNumber(value: false as Bool)
    message.sendTopicID = NSNumber(value: false as Bool)
    message.sendObjectScope = NSNumber(value: false as Bool)
    
    // Send the push message.
    topic.send(message, with: { (topic , error : Error?) -> Void in
      if error != nil {
        // Handle the error.
        return
      }
    })

Objective-C:

  • NSError *error = nil;
    
    // Create APNs-specific data.
    KiiAPNSFields *apnsFields = [KiiAPNSFields createFields];
    [apnsFields setAlertBody:@"Looooooooooooooooooong Message!!"];
    
    // Create a push message with the default keys suppressed.
    KiiPushMessage *pushMessage = [KiiPushMessage composeMessageWithData:nil];
    pushMessage.apnsFields = apnsFields;
    [pushMessage setSendSender:[NSNumber numberWithBool:NO]];
    [pushMessage setSendWhen:[NSNumber numberWithBool:NO]];
    [pushMessage setSendTopicID:[NSNumber numberWithBool:NO]];
    [pushMessage setSendObjectScope:[NSNumber numberWithBool:NO]];
    
    // Send the push message.
    [topic sendMessageSynchronous:pushMessage
                        withError:&error];
    if (error != nil) {
      // Handle the error.
      return;
    }
  • // Create APNs-specific data.
    KiiAPNSFields *apnsFields = [KiiAPNSFields createFields];
    [apnsFields setAlertBody:@"Looooooooooooooooooong Message!!"];
    
    // Create a push message with the default keys suppressed.
    KiiPushMessage *pushMessage = [KiiPushMessage composeMessageWithData:nil];
    pushMessage.apnsFields = apnsFields;
    [pushMessage setSendSender:[NSNumber numberWithBool:NO]];
    [pushMessage setSendWhen:[NSNumber numberWithBool:NO]];
    [pushMessage setSendTopicID:[NSNumber numberWithBool:NO]];
    [pushMessage setSendObjectScope:[NSNumber numberWithBool:NO]];
    
    // Send the push message.
    [topic sendMessage:pushMessage
             withBlock:^(KiiTopic *topic, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
    }];

上記のコードにより送信されるプッシュメッセージは以下のようになります。

{
  aps = {
    alert = {
      body = "Looooooooooooooooooong Message!!";
    };
  };
}

デフォルトキーを抑制するには、KiiPushMessage インスタンスを作成する際に以下のメソッドに対して false を指定します。

抑制するキー 送信抑制のためのメソッド名
s setSendSender
sa, st, sg, su setSendObjectScope
to setSendTopicID
w setSendWhen