Skip to content

Commit

Permalink
Add support for starting a Live Activity
Browse files Browse the repository at this point in the history
  • Loading branch information
ifrins committed Aug 17, 2024
1 parent da5f8b9 commit b3c0583
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,15 @@ public abstract class ApnsPayloadBuilder {
private boolean preferStringRepresentationForAlerts = false;

private LiveActivityEvent event = null;
private String attributesType = null;
private Integer inputPushToken = null;

private Instant timestamp = null;

private Instant dismissalDate = null;

private Map<String, Object> contentState = null;
private Map<String, Object> attributes = null;

private static final String APS_KEY = "aps";
private static final String ALERT_KEY = "alert";
Expand Down Expand Up @@ -123,6 +126,9 @@ public abstract class ApnsPayloadBuilder {
private static final String DISMISSAL_DATE_KEY = "dismissal-date";
private static final String EVENT_KEY = "event";
private static final String CONTENT_STATE_KEY = "content-state";
private static final String INPUT_PUSH_TOKEN_KEY = "input-push-token";
private static final String ATTRIBUTES_TYPE_KEY = "attributes-type";
private static final String ATTRIBUTES_KEY = "attributes";

public static final String[] EMPTY_STRING_ARRAY = new String[0];

Expand Down Expand Up @@ -747,6 +753,24 @@ public ApnsPayloadBuilder setContentState(final Map<String, Object> contentState
return this;
}

/**
* <p>Sets the attributes object that will be used to start the Live Activities.</p>
*
* <p>The precise strategy for serializing the values of custom properties is defined by the specific
* {@code ApnsPayloadBuilder} implementation.</p>
*
* @param attributes attributes object
*
* @return a reference to this payload builder
*
* @see <a href="https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications">
* Starting and updating Live Activities with ActivityKit push notifications</a>
*/
public ApnsPayloadBuilder setAttributes(final Map<String, Object> attributes) {
this.attributes = attributes;
return this;
}

/**
* <p>Sets whether the notification payload will be used for updating the Live Activity
* or for ending it.</p>
Expand Down Expand Up @@ -778,6 +802,32 @@ public ApnsPayloadBuilder setTimestamp(final Instant timestamp) {
return this;
}

/**
* <p>Sets the flag to wake up the app and receive a push token to send updates to the started Live Activity.</p>
*
* @return a reference to this payload builder
*
* @see <a href="https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications">
* Starting and updating Live Activities with ActivityKit push notifications</a>
*/
public ApnsPayloadBuilder setInputPushToken() {
this.inputPushToken = 1;
return this;
}

/**
* <p>Sets the type of the content inside attributes that will be used to start the Live Activity..</p>
*
* @return a reference to this payload builder
*
* @see <a href="https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications">
* Starting and updating Live Activities with ActivityKit push notifications</a>
*/
public ApnsPayloadBuilder setAttributesType(final String attributesType) {
this.attributesType = attributesType;
return this;
}

/**
* <p>Sets a timestamp for the push notification payload. The timestamp is used to discard older
* push notifications. According to Apple's documentation:</p>
Expand Down Expand Up @@ -869,6 +919,10 @@ protected Map<String, Object> buildPayloadMap() {
aps.put(CONTENT_STATE_KEY, this.contentState);
}

if (this.attributes != null) {
aps.put(ATTRIBUTES_KEY, this.attributes);
}

if (this.dismissalDate != null) {
aps.put(DISMISSAL_DATE_KEY, this.dismissalDate.getEpochSecond());
}
Expand Down Expand Up @@ -949,6 +1003,14 @@ protected Map<String, Object> buildPayloadMap() {
aps.put(ALERT_KEY, alert);
}

if (this.attributesType != null) {
aps.put(ATTRIBUTES_TYPE_KEY, this.attributesType);
}

if (this.inputPushToken != null) {
aps.put(INPUT_PUSH_TOKEN_KEY, this.inputPushToken);
}

payload.put(APS_KEY, aps);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
* @since 0.15.2
*/
public enum LiveActivityEvent {
/**
* Used to start a Live Activity.
*/
START("start"),
/**
* Used to update a Live Activity.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,51 @@ void testAddContentStateProperty() {
assertEquals(subMap, serializedContentState.get(keyForMapValue));
}

@Test
void testAddAttributesProperty() {
final String keyForStringValue = "string";
final String stringValue = "Hello";

final String keyForLongValue = "integer";
final long longValue = 12;

final String keyForMapValue = "map";
final Map<String, Object> attributes = new HashMap<>();
final Map<String, Object> subMap = new HashMap<>();
subMap.put("boolean", true);
attributes.put(keyForLongValue, longValue);
attributes.put(keyForStringValue, stringValue);
attributes.put(keyForMapValue, subMap);

this.builder.setAttributes(attributes);

final Map<String, Object> aps = this.extractApsObjectFromPayloadString(this.builder.build());
final Map<String, Object> serializedContentState = (Map<String, Object>) aps.get("attributes");

assertEquals(stringValue, serializedContentState.get(keyForStringValue));
assertEquals(longValue, serializedContentState.get(keyForLongValue));
assertEquals(subMap, serializedContentState.get(keyForMapValue));
}

@Test
void setAttributesType() {
final String attributesType = "my-attributes-type";
this.builder.setAttributesType(attributesType);

final Map<String, Object> aps = this.extractApsObjectFromPayloadString(this.builder.build());

assertEquals(attributesType, aps.get("attributes-type"));
}

@Test
void setInputPushToken() {
this.builder.setInputPushToken();

final Map<String, Object> aps = this.extractApsObjectFromPayloadString(this.builder.build());

assertEquals(1L, aps.get("input-push-token"));
}

@SuppressWarnings("unchecked")
private Map<String, Object> extractApsObjectFromPayloadString(final String payloadString) {
final Map<String, Object> payload;
Expand Down

0 comments on commit b3c0583

Please sign in to comment.