Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion Sources/MessagingInApp/Extensions/GistExtensions.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import Foundation

extension Message {
extension Message: CustomStringConvertible {
// Used for getting details about the Message object for sending to logs.
//
// We are logging the Gist campaign id as delivery id because we call it delivery id on our system.
var describeForLogs: String {
"id: \(messageId), queueId: \(queueId ?? "none"), deliveryId: \(gistProperties.campaignId ?? "none")"
}

// Provides string representation of Message object with all its properties for debugging purposes.
public var description: String {
"Message(messageId=\(messageId), instanceId=\(instanceId), priority=\(String(describing: priority)), queueId=\(String(describing: queueId)), properties=\(gistProperties))"
}
}

extension GistProperties: CustomStringConvertible {
// Provides string representation of GistProperties object with all its properties for debugging purposes.
public var description: String {
"GistProperties(routeRule=\(String(describing: routeRule)), elementId=\(String(describing: elementId)), deliveryId=\(String(describing: campaignId)), position=\(position), persistent=\(String(describing: persistent)))"
}
}
9 changes: 3 additions & 6 deletions Sources/MessagingInApp/Gist/Managers/MessageManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class MessageManager: EngineWebDelegate {
private let currentMessage: Message
private var currentRoute: String
private let isMessageEmbed: Bool
private var messagePosition: MessagePosition = .center

@Atomic private var isMessageLoaded: Bool = false
private var inAppMessageStoreSubscriber: InAppMessageStoreSubscriber?
Expand Down Expand Up @@ -79,9 +78,8 @@ class MessageManager: EngineWebDelegate {
}()
}

func showMessage(position: MessagePosition) {
func showMessage() {
elapsedTimer.start(title: "Displaying modal for message: \(currentMessage.messageId)")
messagePosition = position
}

private func loadModalMessage() {
Expand All @@ -91,7 +89,7 @@ class MessageManager: EngineWebDelegate {
}

logger.logWithModuleTag("Loading modal message: \(currentMessage.describeForLogs)", level: .debug)
modalViewManager = ModalViewManager(gistView: gistView, position: messagePosition)
modalViewManager = ModalViewManager(gistView: gistView, position: currentMessage.gistProperties.position)
modalViewManager?.showModalView { [weak self] in
guard let self = self else { return }

Expand Down Expand Up @@ -147,6 +145,7 @@ class MessageManager: EngineWebDelegate {
}
} else {
if system {
inAppMessageManager.dispatch(action: .dismissMessage(message: currentMessage, shouldLog: false))
if let url = URL(string: action), UIApplication.shared.canOpenURL(url) {
/*
There are 2 types of deep links:
Expand All @@ -171,14 +170,12 @@ class MessageManager: EngineWebDelegate {
UIApplication.shared.open(url) { handled in
if handled {
self.logger.logWithModuleTag("Dismissing from system action: \(action)", level: .info)
self.inAppMessageManager.dispatch(action: .dismissMessage(message: self.currentMessage, shouldLog: false))
} else {
self.logger.logWithModuleTag("System action not handled", level: .info)
}
}
} else {
logger.logWithModuleTag("Handled by NSUserActivity", level: .info)
inAppMessageManager.dispatch(action: .dismissMessage(message: currentMessage))
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions Sources/MessagingInApp/State/InAppMessageAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ enum InAppMessageAction: Equatable, Action {
case setPageRoute(route: String)
case processMessageQueue(messages: [Message])
case clearMessageQueue
case loadMessage(message: Message, position: MessagePosition? = nil)
case loadMessage(message: Message)
case embedMessage(message: Message, elementId: String)
case displayMessage(message: Message)
case dismissMessage(message: Message, shouldLog: Bool = true, viaCloseAction: Bool = true)
Expand Down Expand Up @@ -46,8 +46,8 @@ enum InAppMessageAction: Equatable, Action {
case (.clearMessageQueue, .clearMessageQueue):
return true

case (.loadMessage(let lhsMessage, let lhsPosition), .loadMessage(let rhsMessage, let rhsPosition)):
return lhsMessage == rhsMessage && lhsPosition == rhsPosition
case (.loadMessage(let lhsMessage), .loadMessage(let rhsMessage)):
return lhsMessage == rhsMessage

case (.embedMessage(let lhsMessage, let lhsElementId), .embedMessage(let rhsMessage, let rhsElementId)):
return lhsMessage == rhsMessage && lhsElementId == rhsElementId
Expand Down
27 changes: 12 additions & 15 deletions Sources/MessagingInApp/State/InAppMessageMiddleware.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func routeMatchingMiddleware(logger: Logger) -> InAppMessageMiddleware {
func modalMessageDisplayStateMiddleware(logger: Logger, threadUtil: ThreadUtil) -> InAppMessageMiddleware {
middleware { _, getState, next, action in
// Continue to next middleware if action is not loadMessage
guard case .loadMessage(let message, let position) = action else {
guard case .loadMessage(let message) = action else {
return next(action)
}

Expand All @@ -65,11 +65,11 @@ func modalMessageDisplayStateMiddleware(logger: Logger, threadUtil: ThreadUtil)
return next(.reportError(message: "Blocked loading message: \(message.describeForLogs) because another message is currently displayed or cancelled: \(currentMessage)"))
}

logger.logWithModuleTag("Showing message: \(message.describeForLogs) with position: \(String(describing: position))", level: .debug)
logger.logWithModuleTag("Showing message: \(message)", level: .debug)
// Show message on main thread to avoid unexpected crashes
threadUtil.runMain {
let messageManager = MessageManager(state: state, message: message)
messageManager.showMessage(position: position ?? .center)
messageManager.showMessage()
}

return next(action)
Expand All @@ -96,9 +96,12 @@ func messageMetricsMiddleware(logger: Logger, logManager: LogManager) -> InAppMe
} else {
logger.logWithModuleTag("Persistent message shown, not logging view for message: \(message.describeForLogs)", level: .debug)
}
return next(action)

case .dismissMessage(let message, let shouldLog, let viaCloseAction):
guard shouldLog else { return }
guard shouldLog else {
return next(action)
}

// Log message close only if message was dismissed via close action
if viaCloseAction {
Expand All @@ -113,9 +116,8 @@ func messageMetricsMiddleware(logger: Logger, logManager: LogManager) -> InAppMe
}

default:
break
return next(action)
}
return next(action)
}
}

Expand All @@ -132,7 +134,8 @@ func messageQueueProcessorMiddleware(logger: Logger) -> InAppMessageMiddleware {
.filter { message in
guard let queueId = message.queueId else { return false }

return !state.shownMessageQueueIds.contains(queueId)
// Filter out messages that have been shown already, or if the message is embedded
return !state.shownMessageQueueIds.contains(queueId) && message.gistProperties.elementId == nil
}
.reduce(into: [Message]()) { result, message in
if !result.contains(where: { $0.queueId == message.queueId }) {
Expand Down Expand Up @@ -168,18 +171,12 @@ func messageQueueProcessorMiddleware(logger: Logger) -> InAppMessageMiddleware {
// This can happen if there is a message currently displayed or loading
// or if there are no messages in the queue that match the current route
logger.logWithModuleTag("No message matched the criteria to be shown", level: .debug)
// We don't need to dispatch next action to process remaining messages since processMessageQueue was already dispatched above
return
}

let elementId = message.gistProperties.elementId
let nextAction: InAppMessageAction
if let elementId {
nextAction = .embedMessage(message: message, elementId: elementId)
} else {
nextAction = .loadMessage(message: message)
}
// Dispatch action to show the message
dispatch(nextAction)
dispatch(.loadMessage(message: message))
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/MessagingInApp/State/InAppMessageReducer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private func reducer(action: InAppMessageAction, state: InAppMessageState) -> In
case .clearMessageQueue:
return state.copy(messagesInQueue: [])

case .loadMessage(let message, _):
case .loadMessage(let message):
return state.copy(currentMessageState: .loading(message: message))

case .displayMessage(let message):
Expand Down