diff --git a/Firebase/InAppMessaging/Flows/FIRIAMDisplayExecutor.h b/Firebase/InAppMessaging/Flows/FIRIAMDisplayExecutor.h index 7137121b477..602ea57787f 100644 --- a/Firebase/InAppMessaging/Flows/FIRIAMDisplayExecutor.h +++ b/Firebase/InAppMessaging/Flows/FIRIAMDisplayExecutor.h @@ -22,6 +22,7 @@ #import "FIRIAMClearcutLogger.h" #import "FIRIAMMessageClientCache.h" #import "FIRIAMTimeFetcher.h" +#import "FIRInAppMessaging.h" #import "FIRInAppMessagingRendering.h" NS_ASSUME_NONNULL_BEGIN @@ -39,13 +40,14 @@ NS_ASSUME_NONNULL_BEGIN // 2 For non-contextual messages, the display interval in display setting is met. @interface FIRIAMDisplayExecutor : NSObject -- (instancetype)initWithSetting:(FIRIAMDisplaySetting *)setting - messageCache:(FIRIAMMessageClientCache *)cache - timeFetcher:(id)timeFetcher - bookKeeper:(id)displayBookKeeper - actionURLFollower:(FIRIAMActionURLFollower *)actionURLFollower - activityLogger:(FIRIAMActivityLogger *)activityLogger - analyticsEventLogger:(id)analyticsEventLogger; +- (instancetype)initWithInAppMessaging:(FIRInAppMessaging *)inAppMessaging + setting:(FIRIAMDisplaySetting *)setting + messageCache:(FIRIAMMessageClientCache *)cache + timeFetcher:(id)timeFetcher + bookKeeper:(id)displayBookKeeper + actionURLFollower:(FIRIAMActionURLFollower *)actionURLFollower + activityLogger:(FIRIAMActivityLogger *)activityLogger + analyticsEventLogger:(id)analyticsEventLogger; // Check and display next in-app message eligible for app open trigger - (void)checkAndDisplayNextAppForegroundMessage; diff --git a/Firebase/InAppMessaging/Flows/FIRIAMDisplayExecutor.m b/Firebase/InAppMessaging/Flows/FIRIAMDisplayExecutor.m index 5cc188df474..ed5cc2868e6 100644 --- a/Firebase/InAppMessaging/Flows/FIRIAMDisplayExecutor.m +++ b/Firebase/InAppMessaging/Flows/FIRIAMDisplayExecutor.m @@ -22,6 +22,7 @@ #import "FIRIAMMessageContentData.h" #import "FIRIAMMessageDefinition.h" #import "FIRIAMSDKRuntimeErrorCodes.h" +#import "FIRInAppMessaging.h" @implementation FIRIAMDisplaySetting @end @@ -32,6 +33,7 @@ @interface FIRIAMDisplayExecutor () // YES if a message is being rendered at this time @property(nonatomic) BOOL isMsgBeingDisplayed; @property(nonatomic) NSTimeInterval lastDisplayTime; +@property(nonatomic, nonnull, readonly) FIRInAppMessaging *inAppMessaging; @property(nonatomic, nonnull, readonly) FIRIAMDisplaySetting *setting; @property(nonatomic, nonnull, readonly) FIRIAMMessageClientCache *messageCache; @property(nonatomic, nonnull, readonly) id displayBookKeeper; @@ -45,7 +47,13 @@ @implementation FIRIAMDisplayExecutor { } #pragma mark - FIRInAppMessagingDisplayDelegate methods -- (void)messageClicked { +- (void)messageClicked:(FIRInAppMessagingDisplayMessage *)inAppMessage { + // Call through to app-side delegate. + __weak id appSideDelegate = self.inAppMessaging.delegate; + if ([appSideDelegate respondsToSelector:@selector(messageClicked:)]) { + [appSideDelegate messageClicked:inAppMessage]; + } + self.isMsgBeingDisplayed = NO; if (!_currentMsgBeingDisplayed.renderData.messageID) { FIRLogWarning(kFIRLoggerInAppMessaging, @"I-IAM400030", @@ -124,7 +132,14 @@ - (void)messageClicked { } } -- (void)messageDismissedWithType:(FIRInAppMessagingDismissType)dismissType { +- (void)messageDismissed:(FIRInAppMessagingDisplayMessage *)inAppMessage + dismissType:(FIRInAppMessagingDismissType)dismissType { + // Call through to app-side delegate. + __weak id appSideDelegate = self.inAppMessaging.delegate; + if ([appSideDelegate respondsToSelector:@selector(messageDismissed:dismissType:)]) { + [appSideDelegate messageDismissed:inAppMessage dismissType:dismissType]; + } + self.isMsgBeingDisplayed = NO; if (!_currentMsgBeingDisplayed.renderData.messageID) { FIRLogWarning(kFIRLoggerInAppMessaging, @"I-IAM400014", @@ -170,7 +185,12 @@ - (void)messageDismissedWithType:(FIRInAppMessagingDismissType)dismissType { }]; } -- (void)impressionDetected { +- (void)impressionDetectedForMessage:(FIRInAppMessagingDisplayMessage *)inAppMessage { + __weak id appSideDelegate = self.inAppMessaging.delegate; + if ([appSideDelegate respondsToSelector:@selector(impressionDetectedForMessage:)]) { + [appSideDelegate impressionDetectedForMessage:inAppMessage]; + } + if (!_currentMsgBeingDisplayed.renderData.messageID) { FIRLogWarning(kFIRLoggerInAppMessaging, @"I-IAM400022", @"impressionDetected called but " @@ -189,7 +209,13 @@ - (void)impressionDetected { } } -- (void)displayErrorEncountered:(NSError *)error { +- (void)displayErrorForMessage:(FIRInAppMessagingDisplayMessage *)inAppMessage + error:(NSError *)error { + __weak id appSideDelegate = self.inAppMessaging.delegate; + if ([appSideDelegate respondsToSelector:@selector(displayErrorForMessage:error:)]) { + [appSideDelegate displayErrorForMessage:inAppMessage error:error]; + } + self.isMsgBeingDisplayed = NO; if (!_currentMsgBeingDisplayed.renderData.messageID) { @@ -283,14 +309,16 @@ - (void)displayMessageLoadError:(NSError *)error { completion:nil]; } -- (instancetype)initWithSetting:(FIRIAMDisplaySetting *)setting - messageCache:(FIRIAMMessageClientCache *)cache - timeFetcher:(id)timeFetcher - bookKeeper:(id)displayBookKeeper - actionURLFollower:(FIRIAMActionURLFollower *)actionURLFollower - activityLogger:(FIRIAMActivityLogger *)activityLogger - analyticsEventLogger:(id)analyticsEventLogger { +- (instancetype)initWithInAppMessaging:(FIRInAppMessaging *)inAppMessaging + setting:(FIRIAMDisplaySetting *)setting + messageCache:(FIRIAMMessageClientCache *)cache + timeFetcher:(id)timeFetcher + bookKeeper:(id)displayBookKeeper + actionURLFollower:(FIRIAMActionURLFollower *)actionURLFollower + activityLogger:(FIRIAMActivityLogger *)activityLogger + analyticsEventLogger:(id)analyticsEventLogger { if (self = [super init]) { + _inAppMessaging = inAppMessaging; _timeFetcher = timeFetcher; _lastDisplayTime = displayBookKeeper.lastDisplayTime; _setting = setting; @@ -334,43 +362,53 @@ - (void)checkAndDisplayNextContextualMessageForAnalyticsEvent:(NSString *)eventN [self.messageCache nextOnFirebaseAnalyticEventDisplayMsg:eventName]; if (nextAnalyticsBasedMessage) { - [self displayForMessage:nextAnalyticsBasedMessage]; + [self displayForMessage:nextAnalyticsBasedMessage + triggerType:FIRInAppMessagingDisplayTriggerTypeOnAnalyticsEvent]; } } } - (FIRInAppMessagingBannerDisplay *) bannerMessageWithMessageDefinition:(FIRIAMMessageDefinition *)definition - imageData:(FIRInAppMessagingImageData *)imageData { + imageData:(FIRInAppMessagingImageData *)imageData + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType { NSString *title = definition.renderData.contentData.titleText; NSString *body = definition.renderData.contentData.bodyText; FIRInAppMessagingBannerDisplay *bannerMessage = [[FIRInAppMessagingBannerDisplay alloc] initWithMessageID:definition.renderData.messageID + campaignName:definition.renderData.name renderAsTestMessage:definition.isTestMessage + triggerType:triggerType titleText:title bodyText:body textColor:definition.renderData.renderingEffectSettings.textColor backgroundColor:definition.renderData.renderingEffectSettings.displayBGColor - imageData:imageData]; + imageData:imageData + actionURL:definition.renderData.contentData.actionURL]; return bannerMessage; } - (FIRInAppMessagingImageOnlyDisplay *) imageOnlyMessageWithMessageDefinition:(FIRIAMMessageDefinition *)definition - imageData:(FIRInAppMessagingImageData *)imageData { - FIRInAppMessagingImageOnlyDisplay *imageOnlyMessage = - [[FIRInAppMessagingImageOnlyDisplay alloc] initWithMessageID:definition.renderData.messageID - renderAsTestMessage:definition.isTestMessage - imageData:imageData]; + imageData:(FIRInAppMessagingImageData *)imageData + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType { + FIRInAppMessagingImageOnlyDisplay *imageOnlyMessage = [[FIRInAppMessagingImageOnlyDisplay alloc] + initWithMessageID:definition.renderData.messageID + campaignName:definition.renderData.name + renderAsTestMessage:definition.isTestMessage + triggerType:triggerType + imageData:imageData + actionURL:definition.renderData.contentData.actionURL]; return imageOnlyMessage; } - (FIRInAppMessagingModalDisplay *) modalViewMessageWithMessageDefinition:(FIRIAMMessageDefinition *)definition - imageData:(FIRInAppMessagingImageData *)imageData { + imageData:(FIRInAppMessagingImageData *)imageData + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType { // For easier reference in this method. FIRIAMMessageRenderData *renderData = definition.renderData; @@ -388,33 +426,44 @@ - (void)checkAndDisplayNextContextualMessageForAnalyticsEvent:(NSString *)eventN FIRInAppMessagingModalDisplay *modalViewMessage = [[FIRInAppMessagingModalDisplay alloc] initWithMessageID:definition.renderData.messageID + campaignName:definition.renderData.name renderAsTestMessage:definition.isTestMessage + triggerType:triggerType titleText:title bodyText:body textColor:renderData.renderingEffectSettings.textColor backgroundColor:renderData.renderingEffectSettings.displayBGColor imageData:imageData - actionButton:actionButton]; + actionButton:actionButton + actionURL:definition.renderData.contentData.actionURL]; return modalViewMessage; } -- (FIRInAppMessagingDisplayMessageBase *) +- (FIRInAppMessagingDisplayMessage *) displayMessageWithMessageDefinition:(FIRIAMMessageDefinition *)definition - imageData:(FIRInAppMessagingImageData *)imageData { + imageData:(FIRInAppMessagingImageData *)imageData + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType { switch (definition.renderData.renderingEffectSettings.viewMode) { case FIRIAMRenderAsBannerView: - return [self bannerMessageWithMessageDefinition:definition imageData:imageData]; + return [self bannerMessageWithMessageDefinition:definition + imageData:imageData + triggerType:triggerType]; case FIRIAMRenderAsModalView: - return [self modalViewMessageWithMessageDefinition:definition imageData:imageData]; + return [self modalViewMessageWithMessageDefinition:definition + imageData:imageData + triggerType:triggerType]; case FIRIAMRenderAsImageOnlyView: - return [self imageOnlyMessageWithMessageDefinition:definition imageData:imageData]; + return [self imageOnlyMessageWithMessageDefinition:definition + imageData:imageData + triggerType:triggerType]; default: return nil; } } -- (void)displayForMessage:(FIRIAMMessageDefinition *)message { +- (void)displayForMessage:(FIRIAMMessageDefinition *)message + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType { _currentMsgBeingDisplayed = message; [message.renderData.contentData loadImageDataWithBlock:^(NSData *_Nullable imageNSData, NSError *error) { @@ -424,8 +473,12 @@ - (void)displayForMessage:(FIRIAMMessageDefinition *)message { FIRLogDebug(kFIRLoggerInAppMessaging, @"I-IAM400019", @"Error in loading image data for the message."); + FIRInAppMessagingDisplayMessage *erroredMessage = + [self displayMessageWithMessageDefinition:message + imageData:imageData + triggerType:triggerType]; // short-circuit to display error handling - [self displayErrorEncountered:error]; + [self displayErrorForMessage:erroredMessage error:error]; return; } else if (imageNSData != nil) { imageData = [[FIRInAppMessagingImageData alloc] @@ -436,8 +489,10 @@ - (void)displayForMessage:(FIRIAMMessageDefinition *)message { self.impressionRecorded = NO; self.isMsgBeingDisplayed = YES; - FIRInAppMessagingDisplayMessageBase *displayMessage = - [self displayMessageWithMessageDefinition:message imageData:imageData]; + FIRInAppMessagingDisplayMessage *displayMessage = + [self displayMessageWithMessageDefinition:message + imageData:imageData + triggerType:triggerType]; [self.messageDisplayComponent displayMessage:displayMessage displayDelegate:self]; }]; } @@ -481,7 +536,8 @@ - (void)checkAndDisplayNextAppForegroundMessage { FIRIAMMessageDefinition *nextForegroundMessage = [self.messageCache nextOnAppOpenDisplayMsg]; if (nextForegroundMessage) { - [self displayForMessage:nextForegroundMessage]; + [self displayForMessage:nextForegroundMessage + triggerType:FIRInAppMessagingDisplayTriggerTypeOnAppForeground]; self.lastDisplayTime = [self.timeFetcher currentTimestampInSeconds]; } else { FIRLogDebug(kFIRLoggerInAppMessaging, @"I-IAM400001", diff --git a/Firebase/InAppMessaging/Public/FIRInAppMessaging.h b/Firebase/InAppMessaging/Public/FIRInAppMessaging.h index 7764b217777..1f5afcbc932 100644 --- a/Firebase/InAppMessaging/Public/FIRInAppMessaging.h +++ b/Firebase/InAppMessaging/Public/FIRInAppMessaging.h @@ -76,5 +76,11 @@ NS_SWIFT_NAME(InAppMessaging) * property so that it can be used for rendering fiam message UIs. */ @property(nonatomic) id messageDisplayComponent; + +/** + * This delegate should be set on the app side to receive message lifecycle events in app runtime. + */ +@property(nonatomic, weak) id delegate; + @end NS_ASSUME_NONNULL_END diff --git a/Firebase/InAppMessaging/Public/FIRInAppMessagingRendering.h b/Firebase/InAppMessaging/Public/FIRInAppMessagingRendering.h index 75e0404550d..17de1ac2c0d 100644 --- a/Firebase/InAppMessaging/Public/FIRInAppMessagingRendering.h +++ b/Firebase/InAppMessaging/Public/FIRInAppMessagingRendering.h @@ -18,6 +18,17 @@ NS_ASSUME_NONNULL_BEGIN +typedef NS_ENUM(NSInteger, FIRInAppMessagingDisplayMessageType) { + FIRInAppMessagingDisplayMessageTypeModal, + FIRInAppMessagingDisplayMessageTypeBanner, + FIRInAppMessagingDisplayMessageTypeImageOnly +}; + +typedef NS_ENUM(NSInteger, FIRInAppMessagingDisplayTriggerType) { + FIRInAppMessagingDisplayTriggerTypeOnAppForeground, + FIRInAppMessagingDisplayTriggerTypeOnAnalyticsEvent +}; + /** Contains the display information for an action button. */ NS_SWIFT_NAME(InAppMessagingActionButton) @@ -60,24 +71,43 @@ NS_SWIFT_NAME(InAppMessagingImageData) imageData:(NSData *)imageData NS_DESIGNATED_INITIALIZER; @end +/** Defines the metadata for the campaign to which a FIAM message belongs. + */ +@interface FIRInAppMessagingCampaignInfo : NSObject + +@property(nonatomic, nonnull, copy, readonly) NSString *messageID; +@property(nonatomic, nonnull, copy, readonly) NSString *campaignName; +@property(nonatomic, readonly) BOOL renderAsTestMessage; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithMessageID:(NSString *)messageID + campaignName:(NSString *)campaignName + renderAsTestMessage:(BOOL)renderAsTestMessage; + +@end + /** * Base class representing a FIAM message to be displayed. Don't create instance * of this class directly. Instantiate one of its subclasses instead. */ -NS_SWIFT_NAME(InAppMessagingDisplayMessageBase) -@interface FIRInAppMessagingDisplayMessageBase : NSObject -@property(nonatomic, copy, nonnull, readonly) NSString *messageID; -@property(nonatomic, readonly) BOOL renderAsTestMessage; +NS_SWIFT_NAME(InAppMessagingDisplayMessage) +@interface FIRInAppMessagingDisplayMessage : NSObject +@property(nonatomic, copy, nonnull, readonly) FIRInAppMessagingCampaignInfo *campaignInfo; +@property(nonatomic, readonly) FIRInAppMessagingDisplayMessageType type; +@property(nonatomic, readonly) FIRInAppMessagingDisplayTriggerType triggerType; - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithMessageID:(NSString *)messageID - renderAsTestMessage:(BOOL)renderAsTestMessage; + campaignName:(NSString *)campaignName + renderAsTestMessage:(BOOL)renderAsTestMessage + messageType:(FIRInAppMessagingDisplayMessageType)messageType + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType; @end /** Class for defining a modal message for display. */ NS_SWIFT_NAME(InAppMessagingModalDisplay) -@interface FIRInAppMessagingModalDisplay : FIRInAppMessagingDisplayMessageBase +@interface FIRInAppMessagingModalDisplay : FIRInAppMessagingDisplayMessage /** * Gets the title for a modal fiam message. @@ -99,6 +129,11 @@ NS_SWIFT_NAME(InAppMessagingModalDisplay) */ @property(nonatomic, nullable, readonly) FIRInAppMessagingActionButton *actionButton; +/** + * Gets the action URL for a modal fiam message. + */ +@property(nonatomic, nullable, readonly) NSURL *actionURL; + /** * Gets the background color for a modal fiam message. */ @@ -111,20 +146,22 @@ NS_SWIFT_NAME(InAppMessagingModalDisplay) - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithMessageID:(NSString *)messageID + campaignName:(NSString *)campaignName renderAsTestMessage:(BOOL)renderAsTestMessage + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType titleText:(NSString *)title bodyText:(NSString *)bodyText textColor:(UIColor *)textColor backgroundColor:(UIColor *)backgroundColor imageData:(nullable FIRInAppMessagingImageData *)imageData actionButton:(nullable FIRInAppMessagingActionButton *)actionButton - NS_DESIGNATED_INITIALIZER; + actionURL:(nullable NSURL *)actionURL NS_DESIGNATED_INITIALIZER; @end /** Class for defining a banner message for display. */ NS_SWIFT_NAME(InAppMessagingBannerDisplay) -@interface FIRInAppMessagingBannerDisplay : FIRInAppMessagingDisplayMessageBase +@interface FIRInAppMessagingBannerDisplay : FIRInAppMessagingDisplayMessage // Title is always required for modal messages. @property(nonatomic, nonnull, copy, readonly) NSString *title; @@ -142,30 +179,46 @@ NS_SWIFT_NAME(InAppMessagingBannerDisplay) */ @property(nonatomic, copy, nonnull) UIColor *textColor; +/** + * Gets the action URL for a banner fiam message. + */ +@property(nonatomic, nullable, readonly) NSURL *actionURL; + - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithMessageID:(NSString *)messageID + campaignName:(NSString *)campaignName renderAsTestMessage:(BOOL)renderAsTestMessage + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType titleText:(NSString *)title bodyText:(NSString *)bodyText textColor:(UIColor *)textColor backgroundColor:(UIColor *)backgroundColor imageData:(nullable FIRInAppMessagingImageData *)imageData - NS_DESIGNATED_INITIALIZER; + actionURL:(nullable NSURL *)actionURL NS_DESIGNATED_INITIALIZER; @end /** Class for defining a image-only message for display. */ NS_SWIFT_NAME(InAppMessagingImageOnlyDisplay) -@interface FIRInAppMessagingImageOnlyDisplay : FIRInAppMessagingDisplayMessageBase +@interface FIRInAppMessagingImageOnlyDisplay : FIRInAppMessagingDisplayMessage /** * Gets the image for this message */ @property(nonatomic, nonnull, copy, readonly) FIRInAppMessagingImageData *imageData; + +/** + * Gets the action URL for an image-only fiam message. + */ +@property(nonatomic, nullable, readonly) NSURL *actionURL; + - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithMessageID:(NSString *)messageID + campaignName:(NSString *)campaignName renderAsTestMessage:(BOOL)renderAsTestMessage - imageData:(FIRInAppMessagingImageData *)imageData NS_DESIGNATED_INITIALIZER; + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType + imageData:(FIRInAppMessagingImageData *)imageData + actionURL:(nullable NSURL *)actionURL NS_DESIGNATED_INITIALIZER; @end typedef NS_ENUM(NSInteger, FIRInAppMessagingDismissType) { @@ -192,15 +245,17 @@ NS_SWIFT_NAME(InAppMessagingDisplayDelegate) @protocol FIRInAppMessagingDisplayDelegate /** * Called when the message is dismissed. Should be called from main thread. + * @param inAppMessage the message that was dismissed. * @param dismissType specifies how the message is closed. */ -- (void)messageDismissedWithType:(FIRInAppMessagingDismissType)dismissType - NS_SWIFT_NAME(messageDismissed(dismissType:)); +- (void)messageDismissed:(FIRInAppMessagingDisplayMessage *)inAppMessage + dismissType:(FIRInAppMessagingDismissType)dismissType; /** * Called when the message's action button is followed by the user. + * @param inAppMessage the message that was clicked. */ -- (void)messageClicked; +- (void)messageClicked:(FIRInAppMessagingDisplayMessage *)inAppMessage; /** * Use this to mark a message as having gone through enough impression so that @@ -217,8 +272,9 @@ NS_SWIFT_NAME(InAppMessagingDisplayDelegate) * in this case. But if the app regards this as a valid impression and does not * want the user to see the same message again, call impressionDetected to mark * a valid impression. + * @param inAppMessage the message for which an impression was detected. */ -- (void)impressionDetected; +- (void)impressionDetectedForMessage:(FIRInAppMessagingDisplayMessage *)inAppMessage; /** * Called when the display component could not render the message due to various reason. @@ -228,8 +284,10 @@ NS_SWIFT_NAME(InAppMessagingDisplayDelegate) * met. Missing this callback in failed rendering attempt would make headless * component think a fiam message is still being rendered and therefore suppress any * future message rendering. + * @param inAppMessage the message that encountered a display error. */ -- (void)displayErrorEncountered:(NSError *)error; +- (void)displayErrorForMessage:(FIRInAppMessagingDisplayMessage *)inAppMessage + error:(NSError *)error; @end /** @@ -245,7 +303,7 @@ NS_SWIFT_NAME(InAppMessagingDisplay) * @param displayDelegate the callback object used to trigger notifications about certain * conditions related to message rendering. */ -- (void)displayMessage:(FIRInAppMessagingDisplayMessageBase *)messageForDisplay +- (void)displayMessage:(FIRInAppMessagingDisplayMessage *)messageForDisplay displayDelegate:(id)displayDelegate; @end NS_ASSUME_NONNULL_END diff --git a/Firebase/InAppMessaging/RenderingObjects/FIRInAppMessagingRenderingDataClasses.m b/Firebase/InAppMessaging/RenderingObjects/FIRInAppMessagingRenderingDataClasses.m index 1148e64ccb1..ac2bb53a3a2 100644 --- a/Firebase/InAppMessaging/RenderingObjects/FIRInAppMessagingRenderingDataClasses.m +++ b/Firebase/InAppMessaging/RenderingObjects/FIRInAppMessagingRenderingDataClasses.m @@ -18,13 +18,19 @@ #import "FIRInAppMessagingRendering.h" -@implementation FIRInAppMessagingDisplayMessageBase +@implementation FIRInAppMessagingDisplayMessage - (instancetype)initWithMessageID:(NSString *)messageID - renderAsTestMessage:(BOOL)renderAsTestMessage { + campaignName:(NSString *)campaignName + renderAsTestMessage:(BOOL)renderAsTestMessage + messageType:(FIRInAppMessagingDisplayMessageType)messageType + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType { if (self = [super init]) { - _messageID = messageID; - _renderAsTestMessage = renderAsTestMessage; + _campaignInfo = [[FIRInAppMessagingCampaignInfo alloc] initWithMessageID:messageID + campaignName:campaignName + renderAsTestMessage:renderAsTestMessage]; + _type = messageType; + _triggerType = triggerType; } return self; } @@ -32,18 +38,26 @@ - (instancetype)initWithMessageID:(NSString *)messageID @implementation FIRInAppMessagingBannerDisplay - (instancetype)initWithMessageID:(NSString *)messageID + campaignName:(NSString *)campaignName renderAsTestMessage:(BOOL)renderAsTestMessage + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType titleText:(NSString *)title bodyText:(NSString *)bodyText textColor:(UIColor *)textColor backgroundColor:(UIColor *)backgroundColor - imageData:(nullable FIRInAppMessagingImageData *)imageData { - if (self = [super initWithMessageID:messageID renderAsTestMessage:renderAsTestMessage]) { + imageData:(nullable FIRInAppMessagingImageData *)imageData + actionURL:(nullable NSURL *)actionURL { + if (self = [super initWithMessageID:messageID + campaignName:campaignName + renderAsTestMessage:renderAsTestMessage + messageType:FIRInAppMessagingDisplayMessageTypeBanner + triggerType:triggerType]) { _title = title; _bodyText = bodyText; _textColor = textColor; _displayBackgroundColor = backgroundColor; _imageData = imageData; + _actionURL = actionURL; } return self; } @@ -52,20 +66,28 @@ - (instancetype)initWithMessageID:(NSString *)messageID @implementation FIRInAppMessagingModalDisplay - (instancetype)initWithMessageID:(NSString *)messageID + campaignName:(NSString *)campaignName renderAsTestMessage:(BOOL)renderAsTestMessage + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType titleText:(NSString *)title bodyText:(NSString *)bodyText textColor:(UIColor *)textColor backgroundColor:(UIColor *)backgroundColor imageData:(nullable FIRInAppMessagingImageData *)imageData - actionButton:(nullable FIRInAppMessagingActionButton *)actionButton { - if (self = [super initWithMessageID:messageID renderAsTestMessage:renderAsTestMessage]) { + actionButton:(nullable FIRInAppMessagingActionButton *)actionButton + actionURL:(nullable NSURL *)actionURL { + if (self = [super initWithMessageID:messageID + campaignName:campaignName + renderAsTestMessage:renderAsTestMessage + messageType:FIRInAppMessagingDisplayMessageTypeModal + triggerType:triggerType]) { _title = title; _bodyText = bodyText; _textColor = textColor; _displayBackgroundColor = backgroundColor; _imageData = imageData; _actionButton = actionButton; + _actionURL = actionURL; } return self; } @@ -74,10 +96,18 @@ - (instancetype)initWithMessageID:(NSString *)messageID @implementation FIRInAppMessagingImageOnlyDisplay - (instancetype)initWithMessageID:(NSString *)messageID + campaignName:(NSString *)campaignName renderAsTestMessage:(BOOL)renderAsTestMessage - imageData:(FIRInAppMessagingImageData *)imageData { - if (self = [super initWithMessageID:messageID renderAsTestMessage:renderAsTestMessage]) { + triggerType:(FIRInAppMessagingDisplayTriggerType)triggerType + imageData:(FIRInAppMessagingImageData *)imageData + actionURL:(nullable NSURL *)actionURL { + if (self = [super initWithMessageID:messageID + campaignName:campaignName + renderAsTestMessage:renderAsTestMessage + messageType:FIRInAppMessagingDisplayMessageTypeModal + triggerType:triggerType]) { _imageData = imageData; + _actionURL = actionURL; } return self; } @@ -106,3 +136,16 @@ - (instancetype)initWithImageURL:(NSString *)imageURL imageData:(NSData *)imageD return self; } @end + +@implementation FIRInAppMessagingCampaignInfo +- (instancetype)initWithMessageID:(NSString *)messageID + campaignName:(NSString *)campaignName + renderAsTestMessage:(BOOL)renderAsTestMessage { + if (self = [super init]) { + _messageID = messageID; + _campaignName = campaignName; + _renderAsTestMessage = renderAsTestMessage; + } + return self; +} +@end diff --git a/Firebase/InAppMessaging/Runtime/FIRIAMRuntimeManager.m b/Firebase/InAppMessaging/Runtime/FIRIAMRuntimeManager.m index f8ccf87b8f8..550b38e8127 100644 --- a/Firebase/InAppMessaging/Runtime/FIRIAMRuntimeManager.m +++ b/Firebase/InAppMessaging/Runtime/FIRIAMRuntimeManager.m @@ -337,13 +337,15 @@ - (void)internalStartRuntimeWithSDKSettings:(FIRIAMSDKSettings *)settings { FIRIAMActionURLFollower *actionFollower = [FIRIAMActionURLFollower actionURLFollower]; - self.displayExecutor = [[FIRIAMDisplayExecutor alloc] initWithSetting:appForegroundDisplaysetting - messageCache:self.messageCache - timeFetcher:timeFetcher - bookKeeper:self.bookKeeper - actionURLFollower:actionFollower - activityLogger:self.activityLogger - analyticsEventLogger:analyticsEventLogger]; + self.displayExecutor = + [[FIRIAMDisplayExecutor alloc] initWithInAppMessaging:[FIRInAppMessaging inAppMessaging] + setting:appForegroundDisplaysetting + messageCache:self.messageCache + timeFetcher:timeFetcher + bookKeeper:self.bookKeeper + actionURLFollower:actionFollower + activityLogger:self.activityLogger + analyticsEventLogger:analyticsEventLogger]; // Setting the display component. It's needed in case headless SDK is initialized after // the display component is already set on FIRInAppMessaging. diff --git a/Firebase/InAppMessagingDisplay/Banner/FIDBannerViewController.m b/Firebase/InAppMessagingDisplay/Banner/FIDBannerViewController.m index 511f7dff694..2f46b77099c 100644 --- a/Firebase/InAppMessagingDisplay/Banner/FIDBannerViewController.m +++ b/Firebase/InAppMessagingDisplay/Banner/FIDBannerViewController.m @@ -14,10 +14,9 @@ * limitations under the License. */ -#import - #import "FIDBannerViewController.h" #import "FIRCore+InAppMessagingDisplay.h" +#import "FIRInAppMessagingRendering.h" @interface FIDBannerViewController () @@ -86,6 +85,10 @@ @implementation FIDBannerViewController return bannerVC; } +- (FIRInAppMessagingDisplayMessage *)inAppMessage { + return self.bannerDisplayMessage; +} + - (void)setupRecognizers { UIPanGestureRecognizer *panSwipeRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanSwipe:)]; diff --git a/Firebase/InAppMessagingDisplay/FIDBaseRenderingViewController.h b/Firebase/InAppMessagingDisplay/FIDBaseRenderingViewController.h index c1bd7154118..a585ad22501 100644 --- a/Firebase/InAppMessagingDisplay/FIDBaseRenderingViewController.h +++ b/Firebase/InAppMessagingDisplay/FIDBaseRenderingViewController.h @@ -16,8 +16,8 @@ #import -#import #import "FIDTimeFetcher.h" +#import "FIRInAppMessagingRendering.h" @protocol FIRInAppMessagingDisplayDelegate; @@ -43,5 +43,9 @@ NS_ASSUME_NONNULL_BEGIN // Call this when end user wants to follow the action url - (void)followActionURL; + +// Returns the in-app message being displayed. Overridden by message type subclasses. +- (nullable FIRInAppMessagingDisplayMessage *)inAppMessage; + @end NS_ASSUME_NONNULL_END diff --git a/Firebase/InAppMessagingDisplay/FIDBaseRenderingViewController.m b/Firebase/InAppMessagingDisplay/FIDBaseRenderingViewController.m index 8b416313a02..953ccf0dfb3 100644 --- a/Firebase/InAppMessagingDisplay/FIDBaseRenderingViewController.m +++ b/Firebase/InAppMessagingDisplay/FIDBaseRenderingViewController.m @@ -14,11 +14,10 @@ * limitations under the License. */ -#import - #import "FIDBaseRenderingViewController.h" #import "FIDTimeFetcher.h" #import "FIRCore+InAppMessagingDisplay.h" +#import "FIRInAppMessagingRendering.h" @interface FIDBaseRenderingViewController () // For fiam messages, it's required to be kMinValidImpressionTime to @@ -35,6 +34,10 @@ @interface FIDBaseRenderingViewController () @implementation FIDBaseRenderingViewController +- (nullable FIRInAppMessagingDisplayMessage *)inAppMessage { + return nil; +} + - (void)viewDidLoad { [super viewDidLoad]; @@ -102,8 +105,8 @@ - (void)minImpressionTimeReached { FIRLogDebug(kFIRLoggerInAppMessagingDisplay, @"I-FID200004", @"Min impression time has been reached."); - if ([self.displayDelegate respondsToSelector:@selector(impressionDetected)]) { - [self.displayDelegate impressionDetected]; + if ([self.displayDelegate respondsToSelector:@selector(impressionDetectedForMessage:)]) { + [self.displayDelegate impressionDetectedForMessage:[self inAppMessage]]; } [NSNotificationCenter.defaultCenter removeObserver:self]; @@ -133,7 +136,7 @@ - (void)dismissView:(FIRInAppMessagingDismissType)dismissType { self.view.window.rootViewController = nil; if (self.displayDelegate) { - [self.displayDelegate messageDismissedWithType:dismissType]; + [self.displayDelegate messageDismissed:[self inAppMessage] dismissType:dismissType]; } else { FIRLogWarning(kFIRLoggerInAppMessagingDisplay, @"I-FID200007", @"Display delegate is nil while message is being dismissed."); @@ -147,7 +150,7 @@ - (void)followActionURL { self.view.window.rootViewController = nil; if (self.displayDelegate) { - [self.displayDelegate messageClicked]; + [self.displayDelegate messageClicked:[self inAppMessage]]; } else { FIRLogWarning(kFIRLoggerInAppMessagingDisplay, @"I-FID200008", @"Display delegate is nil while trying to follow action URL."); diff --git a/Firebase/InAppMessagingDisplay/FIRIAMDefaultDisplayImpl.m b/Firebase/InAppMessagingDisplay/FIRIAMDefaultDisplayImpl.m index cf8005f755f..b3d4507c22a 100644 --- a/Firebase/InAppMessagingDisplay/FIRIAMDefaultDisplayImpl.m +++ b/Firebase/InAppMessagingDisplay/FIRIAMDefaultDisplayImpl.m @@ -17,8 +17,6 @@ #import #import -#import -#import #import "FIDBannerViewController.h" #import "FIDImageOnlyViewController.h" @@ -27,6 +25,8 @@ #import "FIDTimeFetcher.h" #import "FIRCore+InAppMessagingDisplay.h" #import "FIRIAMDefaultDisplayImpl.h" +#import "FIRInAppMessaging.h" +#import "FIRInAppMessagingRendering.h" @implementation FIRIAMDefaultDisplayImpl @@ -78,7 +78,7 @@ + (void)displayModalViewWithMessageDefinition:(FIRInAppMessagingModalDisplay *)m NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain code:FIAMDisplayRenderErrorTypeUnspecifiedError userInfo:@{@"message" : @"resource bundle is missing"}]; - [displayDelegate displayErrorEncountered:error]; + [displayDelegate displayErrorForMessage:modalMessage error:error]; return; } @@ -96,7 +96,7 @@ + (void)displayModalViewWithMessageDefinition:(FIRInAppMessagingModalDisplay *)m NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain code:FIAMDisplayRenderErrorTypeUnspecifiedError userInfo:@{}]; - [displayDelegate displayErrorEncountered:error]; + [displayDelegate displayErrorForMessage:modalMessage error:error]; return; } @@ -115,7 +115,7 @@ + (void)displayBannerViewWithMessageDefinition:(FIRInAppMessagingBannerDisplay * NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain code:FIAMDisplayRenderErrorTypeUnspecifiedError userInfo:@{}]; - [displayDelegate displayErrorEncountered:error]; + [displayDelegate displayErrorForMessage:bannerMessage error:error]; return; } @@ -133,7 +133,7 @@ + (void)displayBannerViewWithMessageDefinition:(FIRInAppMessagingBannerDisplay * NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain code:FIAMDisplayRenderErrorTypeUnspecifiedError userInfo:@{}]; - [displayDelegate displayErrorEncountered:error]; + [displayDelegate displayErrorForMessage:bannerMessage error:error]; return; } @@ -153,7 +153,7 @@ + (void)displayImageOnlyViewWithMessageDefinition: NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain code:FIAMDisplayRenderErrorTypeUnspecifiedError userInfo:@{}]; - [displayDelegate displayErrorEncountered:error]; + [displayDelegate displayErrorForMessage:imageOnlyMessage error:error]; return; } @@ -171,7 +171,7 @@ + (void)displayImageOnlyViewWithMessageDefinition: NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain code:FIAMDisplayRenderErrorTypeUnspecifiedError userInfo:@{}]; - [displayDelegate displayErrorEncountered:error]; + [displayDelegate displayErrorForMessage:imageOnlyMessage error:error]; return; } @@ -182,7 +182,7 @@ + (void)displayImageOnlyViewWithMessageDefinition: } #pragma mark - protocol FIRInAppMessagingDisplay -- (void)displayMessage:(FIRInAppMessagingDisplayMessageBase *)messageForDisplay +- (void)displayMessage:(FIRInAppMessagingDisplayMessage *)messageForDisplay displayDelegate:(id)displayDelegate { if ([messageForDisplay isKindOfClass:[FIRInAppMessagingModalDisplay class]]) { FIRLogDebug(kFIRLoggerInAppMessagingDisplay, @"I-FID100000", @"Display a modal message"); @@ -208,7 +208,7 @@ - (void)displayMessage:(FIRInAppMessagingDisplayMessageBase *)messageForDisplay NSError *error = [NSError errorWithDomain:kFirebaseInAppMessagingDisplayErrorDomain code:FIAMDisplayRenderErrorTypeUnspecifiedError userInfo:@{}]; - [displayDelegate displayErrorEncountered:error]; + [displayDelegate displayErrorForMessage:messageForDisplay error:error]; } } @end diff --git a/Firebase/InAppMessagingDisplay/ImageOnly/FIDImageOnlyViewController.m b/Firebase/InAppMessagingDisplay/ImageOnly/FIDImageOnlyViewController.m index c395f5a0d19..aa87fb31701 100644 --- a/Firebase/InAppMessagingDisplay/ImageOnly/FIDImageOnlyViewController.m +++ b/Firebase/InAppMessagingDisplay/ImageOnly/FIDImageOnlyViewController.m @@ -14,10 +14,9 @@ * limitations under the License. */ -#import - #import "FIDImageOnlyViewController.h" #import "FIRCore+InAppMessagingDisplay.h" +#import "FIRInAppMessagingRendering.h" @interface FIDImageOnlyViewController () @@ -56,6 +55,10 @@ @implementation FIDImageOnlyViewController return imageOnlyVC; } +- (FIRInAppMessagingDisplayMessage *)inAppMessage { + return self.imageOnlyMessage; +} + - (IBAction)closeButtonClicked:(id)sender { [self dismissView:FIRInAppMessagingDismissTypeUserTapClose]; } @@ -151,7 +154,7 @@ - (void)viewWillAppear:(BOOL)animated { to:nil from:nil forEvent:nil]; - if (self.imageOnlyMessage.renderAsTestMessage) { + if (self.imageOnlyMessage.campaignInfo.renderAsTestMessage) { FIRLogDebug(kFIRLoggerInAppMessagingDisplay, @"I-FID110004", @"Flashing the close button since this is a test message."); [self flashCloseButton:self.closeButton]; diff --git a/Firebase/InAppMessagingDisplay/Modal/FIDModalViewController.m b/Firebase/InAppMessagingDisplay/Modal/FIDModalViewController.m index 8e31910c0e1..40862db032f 100644 --- a/Firebase/InAppMessagingDisplay/Modal/FIDModalViewController.m +++ b/Firebase/InAppMessagingDisplay/Modal/FIDModalViewController.m @@ -16,10 +16,9 @@ #import -#import - #import "FIDModalViewController.h" #import "FIRCore+InAppMessagingDisplay.h" +#import "FIRInAppMessagingRendering.h" @interface FIDModalViewController () @@ -95,6 +94,10 @@ @implementation FIDModalViewController return modalVC; } +- (FIRInAppMessagingDisplayMessage *)inAppMessage { + return self.modalDisplayMessage; +} + - (IBAction)closeButtonClicked:(id)sender { [self dismissView:FIRInAppMessagingDismissTypeUserTapClose]; } @@ -428,7 +431,7 @@ - (void)viewWillAppear:(BOOL)animated { from:nil forEvent:nil]; - if (self.modalDisplayMessage.renderAsTestMessage) { + if (self.modalDisplayMessage.campaignInfo.renderAsTestMessage) { FIRLogDebug(kFIRLoggerInAppMessagingDisplay, @"I-FID300011", @"Flushing the close button since this is a test message."); [self flashCloseButton:self.closeButton]; diff --git a/Firebase/InAppMessagingDisplay/Public/FIRIAMDefaultDisplayImpl.h b/Firebase/InAppMessagingDisplay/Public/FIRIAMDefaultDisplayImpl.h index 41f6ba39d5a..47f735228de 100644 --- a/Firebase/InAppMessagingDisplay/Public/FIRIAMDefaultDisplayImpl.h +++ b/Firebase/InAppMessagingDisplay/Public/FIRIAMDefaultDisplayImpl.h @@ -14,9 +14,10 @@ * limitations under the License. */ -#import #import +#import "FIRInAppMessagingRendering.h" + NS_ASSUME_NONNULL_BEGIN NS_SWIFT_NAME(InAppMessagingDefaultDisplayImpl) /** @@ -25,7 +26,7 @@ NS_SWIFT_NAME(InAppMessagingDefaultDisplayImpl) * to help UI Testing app access the UI layer directly. */ @interface FIRIAMDefaultDisplayImpl : NSObject -- (void)displayMessage:(FIRInAppMessagingDisplayMessageBase *)messageForDisplay +- (void)displayMessage:(FIRInAppMessagingDisplayMessage *)messageForDisplay displayDelegate:(id)displayDelegate; @end NS_ASSUME_NONNULL_END diff --git a/Firestore/Swift/Source/Codable/CodableGeoPoint.swift b/Firestore/Swift/Source/Codable/CodableGeoPoint.swift index fa563403c8d..487ce9b5db3 100644 --- a/Firestore/Swift/Source/Codable/CodableGeoPoint.swift +++ b/Firestore/Swift/Source/Codable/CodableGeoPoint.swift @@ -24,7 +24,7 @@ import FirebaseFirestore * marked required but that can't be done in an extension. Declaring the extension on the protocol * sidesteps this issue. */ -fileprivate protocol CodableGeoPoint: Codable { +private protocol CodableGeoPoint: Codable { var latitude: Double { get } var longitude: Double { get } @@ -32,7 +32,7 @@ fileprivate protocol CodableGeoPoint: Codable { } /** The keys in a GeoPoint. Must match the properties of CodableGeoPoint. */ -fileprivate enum GeoPointKeys: String, CodingKey { +private enum GeoPointKeys: String, CodingKey { case latitude case longitude } diff --git a/InAppMessaging/Example/Tests/FIRIAMDisplayExecutorTests.m b/InAppMessaging/Example/Tests/FIRIAMDisplayExecutorTests.m index f71a32abe60..79ab4681286 100644 --- a/InAppMessaging/Example/Tests/FIRIAMDisplayExecutorTests.m +++ b/InAppMessaging/Example/Tests/FIRIAMDisplayExecutorTests.m @@ -21,6 +21,7 @@ #import "FIRIAMDisplayExecutor.h" #import "FIRIAMDisplayTriggerDefinition.h" #import "FIRIAMMessageContentData.h" +#import "FIRInAppMessaging.h" // A class implementing protocol FIRIAMMessageContentData to be used for unit testing @interface FIRIAMMessageContentDataForTesting : NSObject @@ -87,7 +88,7 @@ @interface FIRIAMMessageDisplayForTesting : NSObject @property FIRInAppMessagingDelegateInteraction delegateInteraction; // used for interaction verificatio -@property FIRInAppMessagingDisplayMessageBase *message; +@property FIRInAppMessagingDisplayMessage *message; - (instancetype)initWithDelegateInteraction:(FIRInAppMessagingDelegateInteraction)interaction; @end @@ -99,29 +100,62 @@ - (instancetype)initWithDelegateInteraction:(FIRInAppMessagingDelegateInteractio return self; } -- (void)displayMessage:(FIRInAppMessagingDisplayMessageBase *)messageForDisplay +- (void)displayMessage:(FIRInAppMessagingDisplayMessage *)messageForDisplay displayDelegate:(id)displayDelegate { self.message = messageForDisplay; switch (self.delegateInteraction) { case FIRInAppMessagingDelegateInteractionClick: - [displayDelegate messageClicked]; + [displayDelegate messageClicked:messageForDisplay]; break; case FIRInAppMessagingDelegateInteractionDismiss: - [displayDelegate messageDismissedWithType:FIRInAppMessagingDismissTypeAuto]; + [displayDelegate messageDismissed:messageForDisplay + dismissType:FIRInAppMessagingDismissTypeAuto]; break; case FIRInAppMessagingDelegateInteractionError: - [displayDelegate displayErrorEncountered:[NSError errorWithDomain:NSURLErrorDomain - code:0 - userInfo:nil]]; + [displayDelegate displayErrorForMessage:messageForDisplay + error:[NSError errorWithDomain:NSURLErrorDomain + code:0 + userInfo:nil]]; break; case FIRInAppMessagingDelegateInteractionImpressionDetected: - [displayDelegate impressionDetected]; + [displayDelegate impressionDetectedForMessage:messageForDisplay]; break; } } @end +@interface FIRInAppMessagingDisplayTestDelegate : NSObject + +@property(nonatomic) BOOL receivedMessageErrorCallback; +@property(nonatomic) BOOL receivedMessageImpressionCallback; +@property(nonatomic) BOOL receivedMessageClickedCallback; +@property(nonatomic) BOOL receivedMessageDismissedCallback; + +@end + +@implementation FIRInAppMessagingDisplayTestDelegate + +- (void)displayErrorForMessage:(nonnull FIRInAppMessagingDisplayMessage *)inAppMessage + error:(nonnull NSError *)error { + self.receivedMessageErrorCallback = YES; +} + +- (void)impressionDetectedForMessage:(nonnull FIRInAppMessagingDisplayMessage *)inAppMessage { + self.receivedMessageImpressionCallback = YES; +} + +- (void)messageClicked:(nonnull FIRInAppMessagingDisplayMessage *)inAppMessage { + self.receivedMessageClickedCallback = YES; +} + +- (void)messageDismissed:(nonnull FIRInAppMessagingDisplayMessage *)inAppMessage + dismissType:(FIRInAppMessagingDismissType)dismissType { + self.receivedMessageDismissedCallback = YES; +} + +@end + @interface FIRIAMDisplayExecutorTests : XCTestCase @property(nonatomic) FIRIAMDisplaySetting *displaySetting; @@ -132,7 +166,7 @@ @interface FIRIAMDisplayExecutorTests : XCTestCase @property FIRIAMDisplayExecutor *displayExecutor; @property FIRIAMActivityLogger *mockActivityLogger; - +@property FIRInAppMessaging *mockInAppMessaging; @property id mockAnalyticsEventLogger; @property FIRIAMActionURLFollower *mockActionURLFollower; @@ -269,28 +303,23 @@ - (void)setUp { self.mockTimeFetcher = OCMProtocolMock(@protocol(FIRIAMTimeFetcher)); self.mockActivityLogger = OCMClassMock([FIRIAMActivityLogger class]); self.mockAnalyticsEventLogger = OCMProtocolMock(@protocol(FIRIAMAnalyticsEventLogger)); - + self.mockInAppMessaging = OCMClassMock([FIRInAppMessaging class]); self.mockActionURLFollower = OCMClassMock([FIRIAMActionURLFollower class]); self.displayExecutor = - [[FIRIAMDisplayExecutor alloc] initWithSetting:self.displaySetting - messageCache:self.clientMessageCache - timeFetcher:self.mockTimeFetcher - bookKeeper:self.mockBookkeeper - actionURLFollower:self.mockActionURLFollower - activityLogger:self.mockActivityLogger - analyticsEventLogger:self.mockAnalyticsEventLogger]; + [[FIRIAMDisplayExecutor alloc] initWithInAppMessaging:self.mockInAppMessaging + setting:self.displaySetting + messageCache:self.clientMessageCache + timeFetcher:self.mockTimeFetcher + bookKeeper:self.mockBookkeeper + actionURLFollower:self.mockActionURLFollower + activityLogger:self.mockActivityLogger + analyticsEventLogger:self.mockAnalyticsEventLogger]; OCMStub([self.mockBookkeeper recordNewImpressionForMessage:[OCMArg any] withStartTimestampInSeconds:1000]); } -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the - // class. - [super tearDown]; -} - - (void)testRegularMessageAvailableCase { // This setup allows next message to be displayed from display interval perspective. OCMStub([self.mockTimeFetcher currentTimestampInSeconds]) @@ -305,7 +334,7 @@ - (void)testRegularMessageAvailableCase { XCTAssertEqual(1, remainingMsgCount); // Verify that the message content handed to display component is expected - XCTAssertEqualObjects(self.m2.renderData.messageID, display.message.messageID); + XCTAssertEqualObjects(self.m2.renderData.messageID, display.message.campaignInfo.messageID); } - (void)testFollowingActionURL { @@ -389,7 +418,7 @@ - (void)testNoDualDisplay { [self.displayExecutor checkAndDisplayNextAppForegroundMessage]; // m2 is being rendered - XCTAssertEqualObjects(self.m2.renderData.messageID, display.message.messageID); + XCTAssertEqualObjects(self.m2.renderData.messageID, display.message.campaignInfo.messageID); NSInteger remainingMsgCount = [self.clientMessageCache allRegularMessages].count; XCTAssertEqual(1, remainingMsgCount); @@ -398,7 +427,7 @@ - (void)testNoDualDisplay { [self.displayExecutor checkAndDisplayNextAppForegroundMessage]; // Verify that the message in display component is still m2 - XCTAssertEqualObjects(self.m2.renderData.messageID, display.message.messageID); + XCTAssertEqualObjects(self.m2.renderData.messageID, display.message.campaignInfo.messageID); // message in cache remain unchanged for the second checkAndDisplayNext call remainingMsgCount = [self.clientMessageCache allRegularMessages].count; @@ -691,7 +720,7 @@ - (void)testOnFirebaseAnalyticsEventDisplayMessages { // from cache [self.displayExecutor checkAndDisplayNextContextualMessageForAnalyticsEvent:@"test_event"]; // Expecting the m1 being used for display - XCTAssertEqualObjects(self.m1.renderData.messageID, display.message.messageID); + XCTAssertEqualObjects(self.m1.renderData.messageID, display.message.campaignInfo.messageID); remainingMsgCount = [self.clientMessageCache allRegularMessages].count; @@ -758,4 +787,84 @@ - (void)testNoContextualMsgRenderingIfMessageDisplayIsSuppressed { // one message was rendered and removed from the cache XCTAssertEqual(1, remainingMsgCount2); } + +- (void)testMessageClickedCallback { + FIRInAppMessagingDisplayTestDelegate *delegate = + [[FIRInAppMessagingDisplayTestDelegate alloc] init]; + self.mockInAppMessaging.delegate = delegate; + + // This setup allows next message to be displayed from display interval perspective. + OCMStub([self.mockTimeFetcher currentTimestampInSeconds]) + .andReturn(DISPLAY_MIN_INTERVALS * 60 + 100); + OCMStub(self.mockInAppMessaging.delegate).andReturn(delegate); + + FIRIAMMessageDisplayForTesting *display = [[FIRIAMMessageDisplayForTesting alloc] + initWithDelegateInteraction:FIRInAppMessagingDelegateInteractionClick]; + self.displayExecutor.messageDisplayComponent = display; + [self.clientMessageCache setMessageData:@[ self.m2, self.m4 ]]; + [self.displayExecutor checkAndDisplayNextAppForegroundMessage]; + + XCTAssertTrue(delegate.receivedMessageClickedCallback); +} + +- (void)testMessageImpressionCallback { + FIRInAppMessagingDisplayTestDelegate *delegate = + [[FIRInAppMessagingDisplayTestDelegate alloc] init]; + self.mockInAppMessaging.delegate = delegate; + + // This setup allows next message to be displayed from display interval perspective. + OCMStub([self.mockTimeFetcher currentTimestampInSeconds]) + .andReturn(DISPLAY_MIN_INTERVALS * 60 + 100); + OCMStub(self.mockInAppMessaging.delegate).andReturn(delegate); + + FIRIAMMessageDisplayForTesting *display = [[FIRIAMMessageDisplayForTesting alloc] + initWithDelegateInteraction:FIRInAppMessagingDelegateInteractionImpressionDetected]; + self.displayExecutor.messageDisplayComponent = display; + [self.clientMessageCache setMessageData:@[ self.m2, self.m4 ]]; + [self.displayExecutor checkAndDisplayNextAppForegroundMessage]; + + // Verify that the message content handed to display component is expected + XCTAssertTrue(delegate.receivedMessageImpressionCallback); +} + +- (void)testMessageErrorCallback { + FIRInAppMessagingDisplayTestDelegate *delegate = + [[FIRInAppMessagingDisplayTestDelegate alloc] init]; + self.mockInAppMessaging.delegate = delegate; + + // This setup allows next message to be displayed from display interval perspective. + OCMStub([self.mockTimeFetcher currentTimestampInSeconds]) + .andReturn(DISPLAY_MIN_INTERVALS * 60 + 100); + OCMStub(self.mockInAppMessaging.delegate).andReturn(delegate); + + FIRIAMMessageDisplayForTesting *display = [[FIRIAMMessageDisplayForTesting alloc] + initWithDelegateInteraction:FIRInAppMessagingDelegateInteractionError]; + self.displayExecutor.messageDisplayComponent = display; + [self.clientMessageCache setMessageData:@[ self.m2, self.m4 ]]; + [self.displayExecutor checkAndDisplayNextAppForegroundMessage]; + + // Verify that the message content handed to display component is expected + XCTAssertTrue(delegate.receivedMessageErrorCallback); +} + +- (void)testMessageDismissedCallback { + FIRInAppMessagingDisplayTestDelegate *delegate = + [[FIRInAppMessagingDisplayTestDelegate alloc] init]; + self.mockInAppMessaging.delegate = delegate; + + // This setup allows next message to be displayed from display interval perspective. + OCMStub([self.mockTimeFetcher currentTimestampInSeconds]) + .andReturn(DISPLAY_MIN_INTERVALS * 60 + 100); + OCMStub(self.mockInAppMessaging.delegate).andReturn(delegate); + + FIRIAMMessageDisplayForTesting *display = [[FIRIAMMessageDisplayForTesting alloc] + initWithDelegateInteraction:FIRInAppMessagingDelegateInteractionDismiss]; + self.displayExecutor.messageDisplayComponent = display; + [self.clientMessageCache setMessageData:@[ self.m2, self.m4 ]]; + [self.displayExecutor checkAndDisplayNextAppForegroundMessage]; + + // Verify that the message content handed to display component is expected + XCTAssertTrue(delegate.receivedMessageDismissedCallback); +} + @end diff --git a/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/BannerMessageViewController.swift b/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/BannerMessageViewController.swift index d219ab042d5..4ed74bada15 100644 --- a/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/BannerMessageViewController.swift +++ b/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/BannerMessageViewController.swift @@ -16,20 +16,19 @@ import UIKit -import FirebaseInAppMessaging - class BannerMessageViewController: CommonMessageTestVC { let displayImpl = InAppMessagingDefaultDisplayImpl() @IBOutlet var verifyLabel: UILabel! - override func messageClicked() { - super.messageClicked() + override func messageClicked(_ inAppMessage: InAppMessagingDisplayMessage) { + super.messageClicked(inAppMessage) verifyLabel.text = "message clicked!" } - override func messageDismissed(dismissType dimissType: FIRInAppMessagingDismissType) { - super.messageClicked() + override func messageDismissed(_ inAppMessage: InAppMessagingDisplayMessage, + dismissType: FIRInAppMessagingDismissType) { + super.messageClicked(inAppMessage) verifyLabel.text = "message dismissed!" } @@ -38,26 +37,32 @@ class BannerMessageViewController: CommonMessageTestVC { let imageRawData = produceImageOfSize(size: CGSize(width: 200, height: 200)) let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) - let modalMessage = InAppMessagingBannerDisplay(messageID: "messageId", - renderAsTestMessage: false, - titleText: normalMessageTitle, - bodyText: normalMessageBody, - textColor: UIColor.black, - backgroundColor: UIColor.blue, - imageData: fiamImageData) - - displayImpl.displayMessage(modalMessage, displayDelegate: self) + let bannerMessage = InAppMessagingBannerDisplay(messageID: "messageId", + campaignName: "testCampaign", + renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, + titleText: normalMessageTitle, + bodyText: normalMessageBody, + textColor: UIColor.black, + backgroundColor: UIColor.blue, + imageData: fiamImageData, + actionURL: URL(string: "http://firebase.com")) + + displayImpl.displayMessage(bannerMessage, displayDelegate: self) } @IBAction func showBannerViewWithoutImageTapped(_ sender: Any) { verifyLabel.text = "Verification Label" let modalMessage = InAppMessagingBannerDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: normalMessageTitle, bodyText: normalMessageBody, textColor: UIColor.black, backgroundColor: UIColor.blue, - imageData: nil) + imageData: nil, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -68,12 +73,15 @@ class BannerMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingBannerDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: normalMessageTitle, bodyText: normalMessageBody, textColor: UIColor.black, backgroundColor: UIColor.blue, - imageData: fiamImageData) + imageData: fiamImageData, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -84,12 +92,15 @@ class BannerMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingBannerDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: normalMessageTitle, bodyText: normalMessageBody, textColor: UIColor.black, backgroundColor: UIColor.blue, - imageData: fiamImageData) + imageData: fiamImageData, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -100,12 +111,15 @@ class BannerMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingBannerDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: normalMessageTitle, bodyText: longBodyText, textColor: UIColor.black, backgroundColor: UIColor.blue, - imageData: fiamImageData) + imageData: fiamImageData, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -116,12 +130,15 @@ class BannerMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingBannerDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: longTitleText, bodyText: normalMessageBody, textColor: UIColor.black, backgroundColor: UIColor.blue, - imageData: fiamImageData) + imageData: fiamImageData, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } diff --git a/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/CommonMessageTestVC.swift b/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/CommonMessageTestVC.swift index 81ca8567622..12292dd445f 100644 --- a/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/CommonMessageTestVC.swift +++ b/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/CommonMessageTestVC.swift @@ -16,22 +16,27 @@ import Foundation -import FirebaseInAppMessaging - class CommonMessageTestVC: UIViewController, InAppMessagingDisplayDelegate { var messageClosedWithClick = false var messageClosedDismiss = false // start of InAppMessagingDisplayDelegate functions - func messageClicked() { + func messageClicked(_ inAppMessage: InAppMessagingDisplayMessage) { print("message clicked to follow action url") messageClosedWithClick = true } - func impressionDetected() { print("valid impression detected") } - func displayErrorEncountered(_ error: Error) { print("error encountered \(error)") } - func messageDismissed(dismissType: FIRInAppMessagingDismissType) { + func impressionDetected(for inAppMessage: InAppMessagingDisplayMessage) { + print("valid impression detected") + } + + func displayError(for inAppMessage: InAppMessagingDisplayMessage, error: Error) { + print("error encountered \(error)") + } + + func messageDismissed(_ inAppMessage: InAppMessagingDisplayMessage, + dismissType: FIRInAppMessagingDismissType) { print("message dimissed with type \(dismissType)") messageClosedDismiss = true } diff --git a/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/ImageOnlyMessageViewController.swift b/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/ImageOnlyMessageViewController.swift index dc43c24c836..1d6a8cfc42e 100644 --- a/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/ImageOnlyMessageViewController.swift +++ b/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/ImageOnlyMessageViewController.swift @@ -14,20 +14,20 @@ * limitations under the License. */ import UIKit -import FirebaseInAppMessaging class ImageOnlyMessageViewController: CommonMessageTestVC { let displayImpl = InAppMessagingDefaultDisplayImpl() @IBOutlet var verifyLabel: UILabel! - override func messageClicked() { - super.messageClicked() + override func messageClicked(_ inAppMessage: InAppMessagingDisplayMessage) { + super.messageClicked(inAppMessage) verifyLabel.text = "message clicked!" } - override func messageDismissed(dismissType dimissType: FIRInAppMessagingDismissType) { - super.messageClicked() + override func messageDismissed(_ inAppMessage: InAppMessagingDisplayMessage, + dismissType: FIRInAppMessagingDismissType) { + super.messageClicked(inAppMessage) verifyLabel.text = "message dismissed!" } @@ -37,9 +37,11 @@ class ImageOnlyMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingImageOnlyDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, - imageData: fiamImageData) - + triggerType: .onAnalyticsEvent, + imageData: fiamImageData, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -49,9 +51,11 @@ class ImageOnlyMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingImageOnlyDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, - imageData: fiamImageData) - + triggerType: .onAnalyticsEvent, + imageData: fiamImageData, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -61,9 +65,11 @@ class ImageOnlyMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingImageOnlyDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, - imageData: fiamImageData) - + triggerType: .onAnalyticsEvent, + imageData: fiamImageData, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -73,9 +79,11 @@ class ImageOnlyMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingImageOnlyDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, - imageData: fiamImageData) - + triggerType: .onAnalyticsEvent, + imageData: fiamImageData, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -84,9 +92,11 @@ class ImageOnlyMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingImageOnlyDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, - imageData: fiamImageData) - + triggerType: .onAnalyticsEvent, + imageData: fiamImageData, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } } diff --git a/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/ModalMessageViewController.swift b/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/ModalMessageViewController.swift index 3a0bc46daae..6ba528acc76 100644 --- a/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/ModalMessageViewController.swift +++ b/InAppMessagingDisplay/Example/FiamDisplaySwiftExample/ModalMessageViewController.swift @@ -15,20 +15,20 @@ */ import UIKit -import FirebaseInAppMessaging class ModalMessageViewController: CommonMessageTestVC { let displayImpl = InAppMessagingDefaultDisplayImpl() @IBOutlet var verifyLabel: UILabel! - override func messageClicked() { - super.messageClicked() + override func messageClicked(_ inAppMessage: InAppMessagingDisplayMessage) { + super.messageClicked(inAppMessage) verifyLabel.text = "message clicked!" } - override func messageDismissed(dismissType dimissType: FIRInAppMessagingDismissType) { - super.messageClicked() + override func messageDismissed(_ inAppMessage: InAppMessagingDisplayMessage, + dismissType: FIRInAppMessagingDismissType) { + super.messageClicked(inAppMessage) verifyLabel.text = "message dismissed!" } @@ -38,13 +38,16 @@ class ModalMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingModalDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: normalMessageTitle, bodyText: normalMessageBody, textColor: UIColor.black, backgroundColor: UIColor.blue, imageData: fiamImageData, - actionButton: defaultActionButton) + actionButton: defaultActionButton, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -52,13 +55,16 @@ class ModalMessageViewController: CommonMessageTestVC { @IBAction func showWithoutImage(_ sender: Any) { verifyLabel.text = "Verification Label" let modalMessage = InAppMessagingModalDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: normalMessageTitle, bodyText: normalMessageBody, textColor: UIColor.black, backgroundColor: UIColor.blue, imageData: nil, - actionButton: defaultActionButton) + actionButton: defaultActionButton, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -69,13 +75,16 @@ class ModalMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingModalDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: normalMessageTitle, bodyText: normalMessageBody, textColor: UIColor.black, backgroundColor: UIColor.blue, imageData: fiamImageData, - actionButton: nil) + actionButton: nil, + actionURL: nil) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -83,13 +92,16 @@ class ModalMessageViewController: CommonMessageTestVC { @IBAction func showWithoutImageAndButton(_ sender: Any) { verifyLabel.text = "Verification Label" let modalMessage = InAppMessagingModalDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: normalMessageTitle, bodyText: normalMessageBody, textColor: UIColor.black, backgroundColor: UIColor.blue, imageData: nil, - actionButton: nil) + actionButton: nil, + actionURL: nil) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -97,13 +109,16 @@ class ModalMessageViewController: CommonMessageTestVC { @IBAction func showWithLargeBody(_ sender: Any) { verifyLabel.text = "Verification Label" let modalMessage = InAppMessagingModalDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: normalMessageTitle, bodyText: longBodyText, textColor: UIColor.black, backgroundColor: UIColor.blue, imageData: nil, - actionButton: defaultActionButton) + actionButton: defaultActionButton, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -114,13 +129,16 @@ class ModalMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingModalDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, - titleText: longBodyText, + triggerType: .onAnalyticsEvent, + titleText: longTitleText, bodyText: longBodyText, textColor: UIColor.black, backgroundColor: UIColor.blue, imageData: fiamImageData, - actionButton: defaultActionButton) + actionButton: defaultActionButton, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -128,13 +146,16 @@ class ModalMessageViewController: CommonMessageTestVC { @IBAction func showWithLargeTitle(_ sender: Any) { verifyLabel.text = "Verification Label" let modalMessage = InAppMessagingModalDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: longBodyText, bodyText: normalMessageBody, textColor: UIColor.black, backgroundColor: UIColor.blue, imageData: nil, - actionButton: defaultActionButton) + actionButton: defaultActionButton, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -142,13 +163,16 @@ class ModalMessageViewController: CommonMessageTestVC { @IBAction func showWithLargeTitleAndBodyWithoutImage(_ sender: Any) { verifyLabel.text = "Verification Label" let modalMessage = InAppMessagingModalDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, - titleText: longBodyText, + triggerType: .onAnalyticsEvent, + titleText: longTitleText, bodyText: longBodyText, textColor: UIColor.black, backgroundColor: UIColor.blue, imageData: nil, - actionButton: defaultActionButton) + actionButton: defaultActionButton, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -156,13 +180,16 @@ class ModalMessageViewController: CommonMessageTestVC { @IBAction func showWithLargeTitleWithoutBodyWithoutImageWithoutButton(_ sender: Any) { verifyLabel.text = "Verification Label" let modalMessage = InAppMessagingModalDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: longBodyText, bodyText: "", textColor: UIColor.black, backgroundColor: UIColor.blue, imageData: nil, - actionButton: nil) + actionButton: nil, + actionURL: nil) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -173,13 +200,16 @@ class ModalMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingModalDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: normalMessageTitle, bodyText: normalMessageBody, textColor: UIColor.black, backgroundColor: UIColor.blue, imageData: fiamImageData, - actionButton: defaultActionButton) + actionButton: defaultActionButton, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } @@ -190,13 +220,16 @@ class ModalMessageViewController: CommonMessageTestVC { let fiamImageData = InAppMessagingImageData(imageURL: "url not important", imageData: imageRawData!) let modalMessage = InAppMessagingModalDisplay(messageID: "messageId", + campaignName: "testCampaign", renderAsTestMessage: false, + triggerType: .onAnalyticsEvent, titleText: normalMessageTitle, bodyText: normalMessageBody, textColor: UIColor.black, backgroundColor: UIColor.blue, imageData: fiamImageData, - actionButton: defaultActionButton) + actionButton: defaultActionButton, + actionURL: URL(string: "http://firebase.com")) displayImpl.displayMessage(modalMessage, displayDelegate: self) } diff --git a/InAppMessagingDisplay/Example/Podfile b/InAppMessagingDisplay/Example/Podfile index d1b566b6a77..239b3e94570 100644 --- a/InAppMessagingDisplay/Example/Podfile +++ b/InAppMessagingDisplay/Example/Podfile @@ -4,5 +4,7 @@ use_frameworks! target 'FiamDisplaySwiftExample' do platform :ios, '8.0' pod 'FirebaseInAppMessagingDisplay', :path => '../..' + pod 'FirebaseInAppMessaging', :path => '../..' + pod 'FirebaseAnalyticsInterop', :path => '../..' end