Making GCM work for iOS device in the background
For every poor soul wondering in quest for an answer to GCM background mystery. I solved it and the problem was in the format. I'm posting the right format as well as Java code needed to send Http request to GCM with some message.
So the Http request should have two field in the header, namely:
Authorization:key="here goes your GCM api key"
Content-Type:application/json for JSON data type
then the message body should be a json dictionary with keys "to" and "notification". For example:
{
"to": "gcm_token_of_the_device",
"notification": {
"sound": "default",
"badge": "2",
"title": "default",
"body": "Test Push!"
}
}
Here is the simple java program (using only java libraries) that sends push to a specified device, using 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();
}
}
}
GCM background notification works on Android; not on iOS
Turns out I need jGcmData.add("notification", jData); instead of jGcmData.add("data", jData); for APNS to process the background notification. Making that change I now see application(didReceiveRemoteNotification:::fetchCompletionHandler) being called and aside from changing how I process the payload I believe my background notification problem is resolved!
(Link to the SO question that helped me find this resolution will be added shortly!)
To clarify:
GCM accepts the payload description as either notification or data
APNS expects it to be notification for the background notification
GCM push notification when iOS app is in the background
In case if someone has the same problem, the solution was for me to add the "priority": "high" to the JSON. This way I get the notifications in the background.
{
"to" : "token...",
"priority": "high",
"notification" : {
"title": "GCM TITLE",
"body" : "FROM GCM",
"badge": "1",
"sound": "default"
}
}
Background GCM Push Notification Not Received on Certain Apple Devices
You should add the priority
parameter to your request. For example
{
"to":".....",
"content_available":true,
"priority": "high", // Add this field corresponds to 10 for APNS
"notification": {
"title":"my title",
"body":"my body",
"sound":"default"
}
}
Here is the GCM reference that mentions the priority
field. In case you do not set the priority level the message is sent via Normal
priority which in APNS's case is highly variable.
Related Topics
Wkwebview Equivalent for Uiwebview's Scalespagetofit
Uipageviewcontroller and Storyboard
Adding a Closure as Target to a Uibutton
Changing Specific Text's Color Using Nsmutableattributedstring in Swift
Subclass Uiapplication With Swift
How to Resize the Iphone/iPad Simulator
Why Uitableviewautomaticdimension Not Working
Adding Custom Fonts to iOS App Finding Their Real Names
How to Use Uiview Autoresizingmask Property Programmatically
Remove Objects with Duplicate Properties from Swift Array
Swift: Issue in Converting String to Double
Swiftui - How to Pass Environmentobject into View Model
What's the Best Way to Detect When the App Is Entering the Background For My View