Repository: relayrides/pushy (java)
Issue: ApnsPayloadBuilder generates simple alert text instead of alert dictionary
The following codesnippet:

```java
final String payload = new ApnsPayloadBuilder()
        .setAlertBody("BODY")
        .setAlertTitle("TITLE")
        .buildWithDefaultMaximumLength();
```

results in this payload:

```json
{
  "aps": {
    "alert": "BODY"
  }
}
```

My expectation would be:

```json
{
  "aps": {
    "alert": {
      "body": "BODY",
      "title": "TITLE"
    }
  }
}
```

So, if I add any property (other than alert body) to the builder, and that property belongs into the alert dictionary, then the dictionary should actually be generated.

Possible fix: ApnsPayloadBuilder#shouldRepresentAlertAsString should additionally consider these properties:
alertTitle, localizedAlertKey and localizedAlertTitleKey

Best regards
Christian Charles

Pull request description: Fix ApnsPayloadBuilder alert body check when title is included (fixes #168)
The current implement just ignored alert.title when deciding whether to set alert as string or dict.

Hoping to fix [#168]. Test included.

Patch:
diff --git a/src/main/java/com/relayrides/pushy/apns/util/ApnsPayloadBuilder.java b/src/main/java/com/relayrides/pushy/apns/util/ApnsPayloadBuilder.java
index 0a1ea3dc..99258bbd 100644
--- a/src/main/java/com/relayrides/pushy/apns/util/ApnsPayloadBuilder.java
+++ b/src/main/java/com/relayrides/pushy/apns/util/ApnsPayloadBuilder.java
@@ -519,6 +519,12 @@ public class ApnsPayloadBuilder {
 	 * should be represented as a dictionary
 	 */
 	private boolean shouldRepresentAlertAsString() {
-		return this.alertBody != null && this.launchImageFileName == null && this.showActionButton && this.localizedActionButtonKey == null;
+		return this.alertBody != null && this.launchImageFileName == null && this.showActionButton
+				&& this.localizedActionButtonKey == null
+				&& this.alertTitle == null
+				&& this.localizedAlertTitleKey == null
+				&& this.localizedAlertKey == null
+				&& this.localizedAlertArguments == null
+				&& this.localizedAlertTitleArguments == null;
 	}
 }


Test patch:
diff --git a/src/test/java/com/relayrides/pushy/apns/util/ApnsPayloadBuilderTest.java b/src/test/java/com/relayrides/pushy/apns/util/ApnsPayloadBuilderTest.java
index 3ffc4e5b..9e49f211 100644
--- a/src/test/java/com/relayrides/pushy/apns/util/ApnsPayloadBuilderTest.java
+++ b/src/test/java/com/relayrides/pushy/apns/util/ApnsPayloadBuilderTest.java
@@ -82,6 +82,23 @@ public class ApnsPayloadBuilderTest {
 		}
 	}
 
+	@Test
+	public void testSetAlertTitleAndBody() throws ParseException {
+		final String alertTitle = "This is a short alert title";
+		final String alertBody = "This is a longer alert body";
+
+		this.builder.setAlertBody(alertBody);
+		this.builder.setAlertTitle(alertTitle);
+
+		{
+			final JSONObject aps = this.extractApsObjectFromPayloadString(this.builder.buildWithDefaultMaximumLength());
+			final JSONObject alert = (JSONObject) aps.get("alert");
+
+			assertEquals(alertTitle, alert.get("title"));
+			assertEquals(alertBody, alert.get("body"));
+		}
+	}
+
 	@SuppressWarnings("unchecked")
 	@Test
 	public void testSetLocalizedAlertMessage() throws ParseException {