Создание 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 не размещает никаких предупреждений/значков/баннеров из этого входящего уведомления.
Ответы
Ответ 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 может обрабатывать входящее уведомление, но это должно произойти, когда ваше приложение находится в фоновом режиме.