urbanairship-core/src/main/java/com/urbanairship/iam/InAppRemoteDataObserver.java
@WorkerThread
    private void processPayload(RemoteDataPayload payload, InAppMessageScheduler scheduler) throws ExecutionException, InterruptedException {
        long lastUpdate = preferenceDataStore.getLong(LAST_PAYLOAD_TIMESTAMP_KEY, -1);

        List<String> messageIds = new ArrayList<>();
        List<InAppMessageScheduleInfo> newSchedules = new ArrayList<>();
        Map<String, String> scheduleIdMap = getScheduleIdMap();

        for (JsonValue messageJson : payload.getData().opt(MESSAGES_JSON_KEY).optList()) {
            long createdTimeStamp, lastUpdatedTimeStamp;

            try {
                createdTimeStamp = DateUtils.parseIso8601(messageJson.optMap().opt(CREATED_JSON_KEY).getString());
                lastUpdatedTimeStamp = DateUtils.parseIso8601(messageJson.optMap().opt(UPDATED_JSON_KEY).getString());
            } catch (ParseException e) {
                Logger.error("Failed to parse in-app message timestamps: " + messageJson, e);
                continue;
            }

            String messageId = InAppMessageScheduleInfo.parseMessageId(messageJson);
            if (UAStringUtil.isEmpty(messageId)) {
                Logger.error("Missing in-app message ID: " + messageJson);
                continue;
            }

            messageIds.add(messageId);

            // Ignore any messages that have not updated since the last payload
            if (lastUpdatedTimeStamp <= lastUpdate) {
                continue;
            }

            // If we do not have a schedule ID for the message ID, try to look it up first
            if (!scheduleIdMap.containsKey(messageId)) {
                Collection<InAppMessageSchedule> schedules = scheduler.getSchedules(messageId).get();

                // Make sure we only have a single schedule for the message ID
                if (schedules.size() > 1) {
                    Logger.debug("InAppRemoteDataObserver - Duplicate schedules for in-app message: " + messageId);
                    continue;
                }

                if (!schedules.isEmpty()) {
                    scheduleIdMap.put(messageId, schedules.iterator().next().getId());
                }
            }

            if (createdTimeStamp > lastUpdate) {
                try {
                    InAppMessageScheduleInfo scheduleInfo = InAppMessageScheduleInfo.fromJson(messageJson, InAppMessage.SOURCE_REMOTE_DATA);
                    if (checkSchedule(scheduleInfo, createdTimeStamp)) {
                        newSchedules.add(scheduleInfo);
                        Logger.debug("New in-app message: " + scheduleInfo);
                    }
                } catch (JsonException e) {
                    Logger.error("Failed to parse in-app message: " + messageJson, e);
                }
            } else if (scheduleIdMap.containsKey(messageId)) {
                String scheduleId = scheduleIdMap.get(messageId);
                try {
                    InAppMessageScheduleEdits edits = InAppMessageScheduleEdits.fromJson(messageJson);

                    // Since we cancel a schedule by setting the end time to 0 (1970), we need to clear
                    // it (-1) if the edits/schedule does not define an end time.
                    if (edits.getEnd() == null) {
                        edits = InAppMessageScheduleEdits.newBuilder(edits)
                                                         .setEnd(-1)
                                                         .build();
                    }

                    InAppMessageSchedule schedule = scheduler.editSchedule(scheduleId, edits).get();
                    if (schedule != null) {
                        Logger.debug("Updated in-app message: " + messageId + " with edits: " + edits);
                    }
                } catch (JsonException e) {
                    Logger.error("Failed ot parse in-app message edits: " + messageId, e);
                }
            }
        }

        // Schedule new in-app messages
        if (!newSchedules.isEmpty()) {
            List<InAppMessageSchedule> schedules = scheduler.schedule(newSchedules).get();
            for (InAppMessageSchedule schedule : schedules) {
                String messageId = schedule.getInfo().getInAppMessage().getId();
                scheduleIdMap.put(messageId, schedule.getId());
            }
        }

        // End any messages that are no longer in the listing
        Set<String> removedMessageIds = new HashSet<>(scheduleIdMap.keySet());
        removedMessageIds.removeAll(messageIds);

        if (!removedMessageIds.isEmpty()) {

            // To cancel, we need to set the end time to 0 (1970). To avoid validation error where
            // start needs to be before end if they are both set, we also need to clear the start.
            // If the schedule comes back, the edits will reapply the start time from the schedule
            // if it is set.
            InAppMessageScheduleEdits edits = InAppMessageScheduleEdits.newBuilder()
                                                                       .setStart(-1)
                                                                       .setEnd(0)
                                                                       .build();
            for (String messageId : removedMessageIds) {
                String scheduleId = scheduleIdMap.remove(messageId);
                scheduler.editSchedule(scheduleId, edits).get();
            }
        }

        // Store data
        setScheduleIdMap(scheduleIdMap);
        preferenceDataStore.put(LAST_PAYLOAD_TIMESTAMP_KEY, payload.getTimestamp());
    }
/**
     * Processes a payload.
     *
     * @param payload The remote data payload.
     * @param scheduler The scheduler.
     */
Processes a payload.
@param payload The remote data payload.
@param scheduler The scheduler.
Processes a payload . @param payload The remote data payload . @param scheduler The scheduler .
@WorkerThread
    private void processPayload(RemoteDataPayload payload, InAppMessageScheduler scheduler) throws ExecutionException, InterruptedException {
        long lastUpdate = preferenceDataStore.getLong(LAST_PAYLOAD_TIMESTAMP_KEY, -1);
        List<String> messageIds = new ArrayList<>();
        List<InAppMessageScheduleInfo> newSchedules = new ArrayList<>();
        Map<String, String> scheduleIdMap = getScheduleIdMap();
        for (JsonValue messageJson : payload.getData().opt(MESSAGES_JSON_KEY).optList()) {
            long createdTimeStamp, lastUpdatedTimeStamp;
            try {
                createdTimeStamp = DateUtils.parseIso8601(messageJson.optMap().opt(CREATED_JSON_KEY).getString());
                lastUpdatedTimeStamp = DateUtils.parseIso8601(messageJson.optMap().opt(UPDATED_JSON_KEY).getString());
            } catch (ParseException e) {
                Logger.error("Failed to parse in-app message timestamps: " + messageJson, e);
                continue;
            }
            String messageId = InAppMessageScheduleInfo.parseMessageId(messageJson);
            if (UAStringUtil.isEmpty(messageId)) {
                Logger.error("Missing in-app message ID: " + messageJson);
                continue;
            }
            messageIds.add(messageId);
            if (lastUpdatedTimeStamp <= lastUpdate) {
                continue;
            }
            if (!scheduleIdMap.containsKey(messageId)) {
                Collection<InAppMessageSchedule> schedules = scheduler.getSchedules(messageId).get();
                if (schedules.size() > 1) {
                    Logger.debug("InAppRemoteDataObserver - Duplicate schedules for in-app message: " + messageId);
                    continue;
                }
                if (!schedules.isEmpty()) {
                    scheduleIdMap.put(messageId, schedules.iterator().next().getId());
                }
            }
            if (createdTimeStamp > lastUpdate) {
                try {
                    InAppMessageScheduleInfo scheduleInfo = InAppMessageScheduleInfo.fromJson(messageJson, InAppMessage.SOURCE_REMOTE_DATA);
                    if (checkSchedule(scheduleInfo, createdTimeStamp)) {
                        newSchedules.add(scheduleInfo);
                        Logger.debug("New in-app message: " + scheduleInfo);
                    }
                } catch (JsonException e) {
                    Logger.error("Failed to parse in-app message: " + messageJson, e);
                }
            } else if (scheduleIdMap.containsKey(messageId)) {
                String scheduleId = scheduleIdMap.get(messageId);
                try {
                    InAppMessageScheduleEdits edits = InAppMessageScheduleEdits.fromJson(messageJson);
                    if (edits.getEnd() == null) {
                        edits = InAppMessageScheduleEdits.newBuilder(edits)
                                                         .setEnd(-1)
                                                         .build();
                    }
                    InAppMessageSchedule schedule = scheduler.editSchedule(scheduleId, edits).get();
                    if (schedule != null) {
                        Logger.debug("Updated in-app message: " + messageId + " with edits: " + edits);
                    }
                } catch (JsonException e) {
                    Logger.error("Failed ot parse in-app message edits: " + messageId, e);
                }
            }
        }
        if (!newSchedules.isEmpty()) {
            List<InAppMessageSchedule> schedules = scheduler.schedule(newSchedules).get();
            for (InAppMessageSchedule schedule : schedules) {
                String messageId = schedule.getInfo().getInAppMessage().getId();
                scheduleIdMap.put(messageId, schedule.getId());
            }
        }
        Set<String> removedMessageIds = new HashSet<>(scheduleIdMap.keySet());
        removedMessageIds.removeAll(messageIds);
        if (!removedMessageIds.isEmpty()) {
            InAppMessageScheduleEdits edits = InAppMessageScheduleEdits.newBuilder()
                                                                       .setStart(-1)
                                                                       .setEnd(0)
                                                                       .build();
            for (String messageId : removedMessageIds) {
                String scheduleId = scheduleIdMap.remove(messageId);
                scheduler.editSchedule(scheduleId, edits).get();
            }
        }
        setScheduleIdMap(scheduleIdMap);
        preferenceDataStore.put(LAST_PAYLOAD_TIMESTAMP_KEY, payload.getTimestamp());
    }
@ WorkerThread private void processPayload ( RemoteDataPayload payload , InAppMessageScheduler scheduler ) throws ExecutionException , InterruptedException { long lastUpdate = preferenceDataStore . getLong ( LAST_PAYLOAD_TIMESTAMP_KEY , - 1 ) ; List < String > messageIds = new ArrayList < > ( ) ; List < InAppMessageScheduleInfo > newSchedules = new ArrayList < > ( ) ; Map < String , String > scheduleIdMap = getScheduleIdMap ( ) ; for ( JsonValue messageJson : payload . getData ( ) . opt ( MESSAGES_JSON_KEY ) . optList ( ) ) { long createdTimeStamp , lastUpdatedTimeStamp ; try { createdTimeStamp = DateUtils . parseIso8601 ( messageJson . optMap ( ) . opt ( CREATED_JSON_KEY ) . getString ( ) ) ; lastUpdatedTimeStamp = DateUtils . parseIso8601 ( messageJson . optMap ( ) . opt ( UPDATED_JSON_KEY ) . getString ( ) ) ; } catch ( ParseException e ) { Logger . error ( "Failed to parse in-app message timestamps: " + messageJson , e ) ; continue ; } String messageId = InAppMessageScheduleInfo . parseMessageId ( messageJson ) ; if ( UAStringUtil . isEmpty ( messageId ) ) { Logger . error ( "Missing in-app message ID: " + messageJson ) ; continue ; } messageIds . add ( messageId ) ; if ( lastUpdatedTimeStamp <= lastUpdate ) { continue ; } if ( ! scheduleIdMap . containsKey ( messageId ) ) { Collection < InAppMessageSchedule > schedules = scheduler . getSchedules ( messageId ) . get ( ) ; if ( schedules . size ( ) > 1 ) { Logger . debug ( "InAppRemoteDataObserver - Duplicate schedules for in-app message: " + messageId ) ; continue ; } if ( ! schedules . isEmpty ( ) ) { scheduleIdMap . put ( messageId , schedules . iterator ( ) . next ( ) . getId ( ) ) ; } } if ( createdTimeStamp > lastUpdate ) { try { InAppMessageScheduleInfo scheduleInfo = InAppMessageScheduleInfo . fromJson ( messageJson , InAppMessage . SOURCE_REMOTE_DATA ) ; if ( checkSchedule ( scheduleInfo , createdTimeStamp ) ) { newSchedules . add ( scheduleInfo ) ; Logger . debug ( "New in-app message: " + scheduleInfo ) ; } } catch ( JsonException e ) { Logger . error ( "Failed to parse in-app message: " + messageJson , e ) ; } } else if ( scheduleIdMap . containsKey ( messageId ) ) { String scheduleId = scheduleIdMap . get ( messageId ) ; try { InAppMessageScheduleEdits edits = InAppMessageScheduleEdits . fromJson ( messageJson ) ; if ( edits . getEnd ( ) == null ) { edits = InAppMessageScheduleEdits . newBuilder ( edits ) . setEnd ( - 1 ) . build ( ) ; } InAppMessageSchedule schedule = scheduler . editSchedule ( scheduleId , edits ) . get ( ) ; if ( schedule != null ) { Logger . debug ( "Updated in-app message: " + messageId + " with edits: " + edits ) ; } } catch ( JsonException e ) { Logger . error ( "Failed ot parse in-app message edits: " + messageId , e ) ; } } } if ( ! newSchedules . isEmpty ( ) ) { List < InAppMessageSchedule > schedules = scheduler . schedule ( newSchedules ) . get ( ) ; for ( InAppMessageSchedule schedule : schedules ) { String messageId = schedule . getInfo ( ) . getInAppMessage ( ) . getId ( ) ; scheduleIdMap . put ( messageId , schedule . getId ( ) ) ; } } Set < String > removedMessageIds = new HashSet < > ( scheduleIdMap . keySet ( ) ) ; removedMessageIds . removeAll ( messageIds ) ; if ( ! removedMessageIds . isEmpty ( ) ) { InAppMessageScheduleEdits edits = InAppMessageScheduleEdits . newBuilder ( ) . setStart ( - 1 ) . setEnd ( 0 ) . build ( ) ; for ( String messageId : removedMessageIds ) { String scheduleId = scheduleIdMap . remove ( messageId ) ; scheduler . editSchedule ( scheduleId , edits ) . get ( ) ; } } setScheduleIdMap ( scheduleIdMap ) ; preferenceDataStore . put ( LAST_PAYLOAD_TIMESTAMP_KEY , payload . getTimestamp ( ) ) ; }
Processes a payload.
Processes a payload .
// Ignore any messages that have not updated since the last payload // If we do not have a schedule ID for the message ID, try to look it up first // Make sure we only have a single schedule for the message ID // Since we cancel a schedule by setting the end time to 0 (1970), we need to clear // it (-1) if the edits/schedule does not define an end time. // Schedule new in-app messages // End any messages that are no longer in the listing // To cancel, we need to set the end time to 0 (1970). To avoid validation error where // start needs to be before end if they are both set, we also need to clear the start. // If the schedule comes back, the edits will reapply the start time from the schedule // if it is set. // Store data