Подтвердить что ты не робот

Создание GCM для устройства iOS в фоновом режиме

Я пытаюсь использовать GCM для клиентов IOS и Android. Кажется, что с IOS отлично работает, когда приложение находится на переднем плане, однако, когда приложение находится в фоновом режиме, центр уведомлений не получает сообщение, а didReceiveRemoteNotification with completionHandler не вызывается.

Я идентифицировал проблему как неверно отформатированное сообщение от GCM к APNS. А именно, как выглядит:

[message: New message, collapse_key: do_not_collapse, from: **************]
В то время как уведомления IOS push должны иметь aps ключ в уведомлении, я прав? Доступно также доступное содержимое для 1. Например:

{    "aps": {        "контент-доступный": 1   },    "data-id": 345 }

Кстати, в первом приложении приложение все равно получает сообщение, проблема только в фоновом режиме. Любые советы о том, как мне подойти к проблеме, чтобы GCM работал как для ios, так и для android?

UPDATE: Это то, что я нашел в сети:

Что касается реальной связи, если приложение находится в фоновом режиме на устройстве iOS, GCM использует APNS для отправки сообщений, причем приложение ведет себя аналогично использованию системы уведомлений Apple. Но когда приложение активно, GCM напрямую связывается с приложением

Итак, сообщение, которое я получил в режиме переднего плана:

[сообщение: новое сообщение, collapse_key: do_not_collapse, from: **************]

Было ли прямое сообщение от GCM (APNS вообще не участвовал в этом деле). Итак, вопрос в том, что APNS переформатирует то, что GCM отправляет ему, чтобы придерживаться формата уведомлений ios? Если да, то откуда я знаю, что APNS действительно что-то делает и отправляет ли мне уведомление в другом формате? Есть ли способ просмотреть журналы входящих данных из APNS?

UPDATE: Хорошо, мне удалось изменить структуру сообщения, и теперь в режиме переднего плана я получаю следующее сообщение:

Получено оповещение: [ "aps": { "alert": "Простые сообщения", "контент-доступный": 1}, collapse_key: do_not_collapse, from: ************** ]

Теперь он, кажется, хорошо отформатирован, но реакция еще не срабатывает, когда приложение находится в фоновом режиме. didReceiveRemoteNotifification completeHandler не вызван! Что я должен искать и где может быть проблема? Может ли квадратная скобка быть проблемой для push-уведомления? Чтобы быть более точным, ios не размещает никаких предупреждений/значков/баннеров из этого входящего уведомления.

4b9b3361

Ответ 1

Для каждой бедной души, интересующейся поиском ответа на загадку фона GCM. Я решил это, и проблема была в формате. Я отправляю правильный формат, а также код Java, необходимый для отправки запроса Http в GCM с некоторым сообщением. Таким образом, запрос Http должен содержать два поля в заголовке, а именно:

Authorization:key="here goes your GCM api key"
Content-Type:application/json for JSON data type

тогда тело сообщения должно быть json-словарем с ключами "to" и "notification". Например:

{
  "to": "gcm_token_of_the_device",
  "notification": {
    "sound": "default",
    "badge": "2",
    "title": "default",
    "body": "Test Push!"
  }
}

Вот простая java-программа (с использованием только java-библиотек), которая отправляет push на указанное устройство, используя GCM:

public class SendMessage {

    //config
    static String apiKey = ""; // Put here your API key
    static String GCM_Token = ""; // put the GCM Token you want to send to here
    static String notification = "{\"sound\":\"default\",\"badge\":\"2\",\"title\":\"default\",\"body\":\"Test Push!\"}"; // put the message you want to send here
    static String messageToSend = "{\"to\":\"" + GCM_Token + "\",\"notification\":" + notification + "}"; // Construct the message.

    public static void main(String[] args) throws IOException {
        try {

            // URL
            URL url = new URL("https://android.googleapis.com/gcm/send");

            System.out.println(messageToSend);
            // Open connection
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            // Specify POST method
            conn.setRequestMethod("POST");

            //Set the headers
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Authorization", "key=" + apiKey);
            conn.setDoOutput(true);

            //Get connection output stream
            DataOutputStream wr = new DataOutputStream(conn.getOutputStream());

            byte[] data = messageToSend.getBytes("UTF-8");
            wr.write(data);

            //Send the request and close
            wr.flush();
            wr.close();

            //Get the response
            int responseCode = conn.getResponseCode();
            System.out.println("\nSending 'POST' request to URL : " + url);
            System.out.println("Response Code : " + responseCode);

            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            //Print result
            System.out.println(response.toString()); //this is a good place to check for errors using the codes in http://androidcommunitydocs.com/reference/com/google/android/gcm/server/Constants.html

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Ответ 2

Важно отметить, что на устройствах iOS, если ваше приложение, использующее GCM, было убито (прокручено в коммутаторе приложений), тогда ваше устройство пробудится только после получения сообщения, если вы отправите уведомление с уведомлением, content_available "и" priority "(установлено значение" high "). Если у вас есть тот или другой, он может работать, когда приложение было убито. Но как только приложение было убито, вы должны иметь все 3 из этих ключей в своей полезной нагрузке.

Что-то вроде этого:

{
    "to": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "notification": {
        "title": "test",
        "body": "my message"
    },
    "priority": "high",
    "content_available": true
}

Ответ 3

Попробуйте установить приоритетный ключ в своей полезной нагрузке в соответствии с документами здесь: https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message

  • нормальный приоритет равен 5 в терминологии APN
  • высокий приоритет равен 10 в терминологии APN

Здесь у вас есть более подробная информация о приоритетах Apple APN и ее поведении здесь: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html

Пример полезной нагрузки:

{
  "to": "gcm_device_token",
  "priority": "high",
  "content_available": false,
  "notification": {
    "sound": "default",
    "badge": "1",
    "title": "Push Title",
    "body": "Push Body"
  }
}

Ответ 4

  • Это для С#, думаю, это может быть help.I также была эта проблема после добавления content_available в true, он сработал. В соответствии с Apple, что ОС понимает, что существует уведомление, когда приложение находится в фоновом режиме.

        JObject notification =new Object(
        new JProperty("to","put token which you get from running client application "),   
        new JProperty("content_available",true),
        new JProperty("priority","high"),
        new JProperty("notification",new JObject(
        new JProperty("title","message"),
        new JProperty("body","test message")
         ))
        );
    

Ответ 5

Использование nodeJS и node-gcm Библиотека npm Я обнаружил, что следующая полезная нагрузка работает для меня для iOS, для Android я ' m посылает немного другую полезную нагрузку, потому что я хочу перехватить все push-уведомления, прежде чем показывать их в панели задач:

{ dryRun: false,
  data: 
   { customKey1: 'CustomValue1',
     customKey2: 'CustomValue2',
     content_available: '1',
     priority: 'high' },
  notification: 
   { title: 'My Title',
     icon: 'ic_launcher',
     body: 'My Body',
     sound: 'default',
     badge: '2' } }

Конечно, вам нужно будет убедиться, что ваше приложение iOS может обрабатывать входящее уведомление, но это должно произойти, когда ваше приложение находится в фоновом режиме.