Skip to content

Commit

Permalink
[MC-1468] Custom templates present and dismiss (Custom Templates Part…
Browse files Browse the repository at this point in the history
… 4) (#332)

* Implement Template Context

* Implement custom template present and dismiss

* Clear template context delegate on dismiss

* Test evaluate custom templates

* Add template present and dismiss tests
  • Loading branch information
nzagorchev authored Jun 14, 2024
1 parent 26175fc commit 29c2ba0
Show file tree
Hide file tree
Showing 28 changed files with 936 additions and 74 deletions.
14 changes: 14 additions & 0 deletions CleverTapSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,10 @@
6BB778CC2BED21CE00A41628 /* CTNotificationAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BB778CA2BED21CE00A41628 /* CTNotificationAction.m */; };
6BB778CE2BEE48C300A41628 /* CTCustomTemplateInAppDataTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BB778CD2BEE48C300A41628 /* CTCustomTemplateInAppDataTest.m */; };
6BB778D02BEE4C3400A41628 /* CTNotificationActionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BB778CF2BEE4C3400A41628 /* CTNotificationActionTest.m */; };
6BB778D22BF267B600A41628 /* CTTemplateContextTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BB778D12BF267B600A41628 /* CTTemplateContextTest.m */; };
6BB778D62BFD26E000A41628 /* CTInAppNotificationDisplayDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BB778D52BFD26DF00A41628 /* CTInAppNotificationDisplayDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
6BB778D72BFD26E000A41628 /* CTInAppNotificationDisplayDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BB778D52BFD26DF00A41628 /* CTInAppNotificationDisplayDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
6BB778D92BFD277400A41628 /* CTCustomTemplatesManager-Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BB778D82BFD277400A41628 /* CTCustomTemplatesManager-Internal.h */; };
6BD334EA2AF2A41F0099E33E /* CTBatchSentDelegateHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BD334E82AF2A41F0099E33E /* CTBatchSentDelegateHelper.h */; };
6BD334EB2AF2A41F0099E33E /* CTBatchSentDelegateHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BD334E82AF2A41F0099E33E /* CTBatchSentDelegateHelper.h */; };
6BD334EC2AF2A41F0099E33E /* CTBatchSentDelegateHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BD334E92AF2A41F0099E33E /* CTBatchSentDelegateHelper.m */; };
Expand Down Expand Up @@ -906,6 +910,9 @@
6BB778CA2BED21CE00A41628 /* CTNotificationAction.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTNotificationAction.m; sourceTree = "<group>"; };
6BB778CD2BEE48C300A41628 /* CTCustomTemplateInAppDataTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTCustomTemplateInAppDataTest.m; sourceTree = "<group>"; };
6BB778CF2BEE4C3400A41628 /* CTNotificationActionTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTNotificationActionTest.m; sourceTree = "<group>"; };
6BB778D12BF267B600A41628 /* CTTemplateContextTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTTemplateContextTest.m; sourceTree = "<group>"; };
6BB778D52BFD26DF00A41628 /* CTInAppNotificationDisplayDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CTInAppNotificationDisplayDelegate.h; sourceTree = "<group>"; };
6BB778D82BFD277400A41628 /* CTCustomTemplatesManager-Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CTCustomTemplatesManager-Internal.h"; sourceTree = "<group>"; };
6BD334E82AF2A41F0099E33E /* CTBatchSentDelegateHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CTBatchSentDelegateHelper.h; sourceTree = "<group>"; };
6BD334E92AF2A41F0099E33E /* CTBatchSentDelegateHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTBatchSentDelegateHelper.m; sourceTree = "<group>"; };
6BD334EF2AF545C70099E33E /* CTInAppStoreTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTInAppStoreTest.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1447,6 +1454,7 @@
6B32A0B22B9F2E8F009ADC57 /* CTTestTemplateProducer.h */,
6B32A0B32B9F2E8F009ADC57 /* CTTestTemplateProducer.m */,
6BB778CD2BEE48C300A41628 /* CTCustomTemplateInAppDataTest.m */,
6BB778D12BF267B600A41628 /* CTTemplateContextTest.m */,
);
path = CustomTemplates;
sourceTree = "<group>";
Expand Down Expand Up @@ -1475,6 +1483,7 @@
6B32A0A02B99033F009ADC57 /* CTCustomTemplateBuilder-Internal.h */,
6BB778C52BECEC2700A41628 /* CTCustomTemplateInAppData.h */,
6BB778C62BECEC2700A41628 /* CTCustomTemplateInAppData.m */,
6BB778D82BFD277400A41628 /* CTCustomTemplatesManager-Internal.h */,
);
path = CustomTemplates;
sourceTree = "<group>";
Expand Down Expand Up @@ -1730,6 +1739,7 @@
6BA3B2DA2B03E926004E834B /* CTQueueType.h */,
6BB778C92BED21CE00A41628 /* CTNotificationAction.h */,
6BB778CA2BED21CE00A41628 /* CTNotificationAction.m */,
6BB778D52BFD26DF00A41628 /* CTInAppNotificationDisplayDelegate.h */,
);
path = CleverTapSDK;
sourceTree = "<group>";
Expand Down Expand Up @@ -1798,6 +1808,7 @@
4E8B816C2AD2B2FD00714BB4 /* CleverTapInternal.h in Headers */,
D014B90220E2FB4F001E0780 /* CTEventBuilder.h in Headers */,
6A6591692AC70FFE005FDE57 /* CTBatchSentDelegate.h in Headers */,
6BB778D72BFD26E000A41628 /* CTInAppNotificationDisplayDelegate.h in Headers */,
07BF465B217F7C41002E166D /* CTInAppDisplayViewController.h in Headers */,
4E25E3D22788889F0008C888 /* CTLoginInfoProvider.h in Headers */,
D0BD75AF241769E40006EE55 /* CleverTap+ProductConfig.h in Headers */,
Expand Down Expand Up @@ -1889,6 +1900,7 @@
6B535FB62AD56C60002A2663 /* CTMultiDelegateManager.h in Headers */,
4EF0D5452AD84BCA0044C48F /* CTSessionManager.h in Headers */,
D0213D4C207D905800FE5740 /* CleverTapSyncDelegate.h in Headers */,
6BB778D92BFD277400A41628 /* CTCustomTemplatesManager-Internal.h in Headers */,
07B94546219EA34300D4C542 /* CTMessageMO+CoreDataProperties.h in Headers */,
48BEA4F62AFB868B00690424 /* CTInAppImagePrefetchManager.h in Headers */,
6BB727332B8F787D009CE7D0 /* CTCustomTemplatesManager.h in Headers */,
Expand Down Expand Up @@ -1982,6 +1994,7 @@
6BB727212B8E55CD009CE7D0 /* CTTemplateContext.h in Headers */,
4E8B816F2AD2BB8A00714BB4 /* CTDispatchQueueManager.h in Headers */,
D01A0894207EC2D400423D6F /* CleverTapInstanceConfig.h in Headers */,
6BB778D62BFD26E000A41628 /* CTInAppNotificationDisplayDelegate.h in Headers */,
4808030E292EB4FB00C06E2F /* CleverTap+PushPermission.h in Headers */,
071EB50C217F6427008F0FAB /* CTCoverImageViewController.h in Headers */,
4E8B81782AD2CB4E00714BB4 /* CTPushPrimerManager.h in Headers */,
Expand Down Expand Up @@ -2410,6 +2423,7 @@
6B32A0B42B9F2E8F009ADC57 /* CTTestTemplateProducer.m in Sources */,
6A2E0B9829D49D5100FCEA5F /* CTVarCacheMock.m in Sources */,
4EAF05022A495DD5009D9D61 /* CleverTapInstanceTests.m in Sources */,
6BB778D22BF267B600A41628 /* CTTemplateContextTest.m in Sources */,
6A2E0B9329D0A5CF00FCEA5F /* CTVariablesTest.m in Sources */,
D02AC2DB276044F70031C1BE /* CleverTapSDKTests.m in Sources */,
32394C2129FA264B00956058 /* CTPreferencesTest.m in Sources */,
Expand Down
1 change: 1 addition & 0 deletions CleverTapSDK/CTConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ extern NSString *CLTAP_PROFILE_IDENTITY_KEY;
#define CLTAP_INAPP_TEMPLATE_ID @"templateId"
#define CLTAP_INAPP_TEMPLATE_DESCRIPTION @"templateDescription"
#define CLTAP_INAPP_VARS @"vars"
#define CLTAP_INAPP_ACTIONS @"actions"

#define CLTAP_INAPP_PREVIEW_TYPE @"wzrk_inapp_type"
#define CLTAP_INAPP_IMAGE_INTERSTITIAL_TYPE @"image-interstitial"
Expand Down
21 changes: 1 addition & 20 deletions CleverTapSDK/CTInAppDisplayViewController.h
Original file line number Diff line number Diff line change
@@ -1,29 +1,10 @@
#import <UIKit/UIKit.h>
#import "CTInAppNotification.h"
#import "CTInAppNotificationDisplayDelegate.h"
#if !(TARGET_OS_TV)
#import "CleverTapJSInterface.h"
#endif

@class CTInAppDisplayViewController;

@protocol CTInAppNotificationDisplayDelegate <NSObject>
- (void)handleNotificationCTA:(NSURL*)ctaURL buttonCustomExtras:(NSDictionary *)buttonCustomExtras forNotification:(CTInAppNotification*)notification fromViewController:(CTInAppDisplayViewController*)controller withExtras:(NSDictionary*)extras;
- (void)notificationDidDismiss:(CTInAppNotification*)notification fromViewController:(CTInAppDisplayViewController*)controller;
/**
Called when in-app button is tapped for requesting push permission.
*/
- (void)handleInAppPushPrimer:(CTInAppNotification*)notification
fromViewController:(CTInAppDisplayViewController*)controller
withFallbackToSettings:(BOOL)isFallbackToSettings;

/**
Called to notify that local in-app push primer is dismissed.
*/
- (void)inAppPushPrimerDidDismissed;
@optional
- (void)notificationDidShow:(CTInAppNotification*)notification fromViewController:(CTInAppDisplayViewController*)controller;
@end

@interface CTInAppDisplayViewController : UIViewController

@property (nonatomic, weak) id <CTInAppNotificationDisplayDelegate> delegate;
Expand Down
4 changes: 2 additions & 2 deletions CleverTapSDK/CTInAppDisplayViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ - (void)showFromWindow:(BOOL)animated {
[self.window setHidden:NO];

void (^completionBlock)(void) = ^ {
if (self.delegate && [self.delegate respondsToSelector:@selector(notificationDidShow:fromViewController:)]) {
[self.delegate notificationDidShow:self.notification fromViewController:self];
if (self.delegate) {
[self.delegate notificationDidShow:self.notification];
}
};

Expand Down
36 changes: 36 additions & 0 deletions CleverTapSDK/CTInAppNotificationDisplayDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// CTInAppNotificationDisplayDelegate.h
// CleverTapSDK
//
// Created by Nikola Zagorchev on 21.05.24.
// Copyright © 2024 CleverTap. All rights reserved.
//

#ifndef CTInAppNotificationDisplayDelegate_h
#define CTInAppNotificationDisplayDelegate_h

@class CTInAppDisplayViewController;

@protocol CTInAppNotificationDisplayDelegate <NSObject>

- (void)notificationDidShow:(CTInAppNotification *)notification;

- (void)handleNotificationCTA:(NSURL *)ctaURL buttonCustomExtras:(NSDictionary *)buttonCustomExtras forNotification:(CTInAppNotification *)notification fromViewController:(CTInAppDisplayViewController *)controller withExtras:(NSDictionary *)extras;

- (void)notificationDidDismiss:(CTInAppNotification *)notification fromViewController:(CTInAppDisplayViewController *)controller;

/**
Called when in-app button is tapped for requesting push permission.
*/
- (void)handleInAppPushPrimer:(CTInAppNotification *)notification
fromViewController:(CTInAppDisplayViewController *)controller
withFallbackToSettings:(BOOL)isFallbackToSettings;

/**
Called to notify that local in-app push primer is dismissed.
*/
- (void)inAppPushPrimerDidDismissed;

@end

#endif /* Header_h */
5 changes: 3 additions & 2 deletions CleverTapSDK/CTInAppUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ typedef NS_ENUM(NSUInteger, CTInAppActionType){

@interface CTInAppUtils : NSObject

+ (CTInAppType)inAppTypeFromString:(NSString* _Nonnull)type;
+ (CTInAppActionType)inAppActionTypeFromString:(NSString* _Nonnull)type;
+ (CTInAppType)inAppTypeFromString:(NSString *_Nonnull)type;
+ (CTInAppActionType)inAppActionTypeFromString:(NSString *_Nonnull)type;
+ (NSString * _Nonnull)inAppActionTypeString:(CTInAppActionType)type;
+ (NSBundle *_Nullable)bundle;
+ (NSString *_Nullable)getXibNameForControllerName:(NSString *_Nonnull)controllerName;

Expand Down
33 changes: 26 additions & 7 deletions CleverTapSDK/CTInAppUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
#import "CTUIUtils.h"
#endif

static NSDictionary *_inAppTypeMap;
static NSDictionary *_inAppActionTypeMap;
static NSDictionary<NSString *, NSNumber *> *_inAppTypeMap;
static NSDictionary<NSString *, NSNumber *> *_inAppActionTypeStringToTypeMap;
static NSDictionary<NSNumber *, NSString *> *_inAppActionTypeTypeToStringMap;

@implementation CTInAppUtils

Expand Down Expand Up @@ -35,24 +36,42 @@ + (CTInAppType)inAppTypeFromString:(NSString*)type {
return [_type integerValue];
}

+ (CTInAppActionType)inAppActionTypeFromString:(NSString* _Nonnull)type {
if (_inAppActionTypeMap == nil) {
_inAppActionTypeMap = @{
+ (NSDictionary<NSNumber *, NSString *> *)inAppActionTypeTypeToStringMap {
if (_inAppActionTypeTypeToStringMap == nil) {
NSDictionary *dict = [self inAppActionTypeStringToTypeMap];
NSMutableDictionary *swapped = [NSMutableDictionary new];
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
swapped[value] = key;
}];
_inAppActionTypeTypeToStringMap = [swapped copy];
}
return _inAppActionTypeTypeToStringMap;
}

+ (NSDictionary<NSString *, NSNumber *> *)inAppActionTypeStringToTypeMap {
if (_inAppActionTypeStringToTypeMap == nil) {
_inAppActionTypeStringToTypeMap = @{
@"close": @(CTInAppActionTypeClose),
@"url": @(CTInAppActionTypeOpenURL),
@"kv": @(CTInAppActionTypeKeyValues),
@"custom-code": @(CTInAppActionTypeCustom),
@"rfp": @(CTInAppActionTypeRequestForPermission)
};
}

NSNumber *_type = type != nil ? _inAppActionTypeMap[type] : @(CTInAppActionTypeUnknown);
return _inAppActionTypeStringToTypeMap;
}

+ (CTInAppActionType)inAppActionTypeFromString:(NSString* _Nonnull)type {
NSNumber *_type = type != nil ? [self inAppActionTypeStringToTypeMap][type] : @(CTInAppActionTypeUnknown);
if (_type == nil) {
_type = @(CTInAppActionTypeUnknown);
}
return [_type integerValue];
}

+ (NSString * _Nonnull)inAppActionTypeString:(CTInAppActionType)type {
return self.inAppActionTypeTypeToStringMap[@(type)];
}

+ (NSBundle *)bundle {
#if CLEVERTAP_NO_INAPP_SUPPORT
Expand Down
3 changes: 2 additions & 1 deletion CleverTapSDK/CTNotificationButton.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import "CTNotificationButton.h"
#import "CTConstants.h"

@interface CTNotificationButton () {

Expand Down Expand Up @@ -30,7 +31,7 @@ - (instancetype)initWithJSON:(NSDictionary *)jsonObject {
self.borderColor = jsonObject[@"border"];
self.backgroundColor = jsonObject[@"bg"];

NSDictionary *actions = jsonObject[@"actions"];
NSDictionary *actions = jsonObject[CLTAP_INAPP_ACTIONS];
if (actions) {
self.action = [[CTNotificationAction alloc] initWithJSON:actions];
if (self.action.error) {
Expand Down
9 changes: 5 additions & 4 deletions CleverTapSDK/CleverTap.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
#import "CTInAppEvaluationManager.h"
#import "CTInAppTriggerManager.h"
#import "CTInAppImagePrefetchManager.h"
#import "CTCustomTemplatesManager.h"
#import "CTCustomTemplatesManager-Internal.h"
#endif

#if !CLEVERTAP_NO_INBOX_SUPPORT
Expand Down Expand Up @@ -523,17 +523,18 @@ - (void)initializeInAppSupport {

CTInAppFCManager *inAppFCManager = [[CTInAppFCManager alloc] initWithConfig:self.config delegateManager:self.delegateManager deviceId:[_deviceInfo.deviceId copy] impressionManager:impressionManager inAppTriggerManager:triggerManager];

CTCustomTemplatesManager *templatesManager = [[CTCustomTemplatesManager alloc] initWithConfig:self.config];

CTInAppDisplayManager *displayManager = [[CTInAppDisplayManager alloc] initWithCleverTap:self
dispatchQueueManager:self.dispatchQueueManager
inAppFCManager:inAppFCManager
impressionManager:impressionManager
inAppStore:inAppStore
imagePrefetchManager:self.imagePrefetchManager];
imagePrefetchManager:self.imagePrefetchManager
templatesManager:templatesManager];

CTInAppEvaluationManager *evaluationManager = [[CTInAppEvaluationManager alloc] initWithAccountId:self.config.accountId deviceId:self.deviceInfo.deviceId delegateManager:self.delegateManager impressionManager:impressionManager inAppDisplayManager:displayManager inAppStore:inAppStore inAppTriggerManager:triggerManager];

CTCustomTemplatesManager *templatesManager = [[CTCustomTemplatesManager alloc] initWithConfig:self.config];

self.customTemplatesManager = templatesManager;
self.inAppFCManager = inAppFCManager;
self.impressionManager = impressionManager;
Expand Down
4 changes: 2 additions & 2 deletions CleverTapSDK/InApps/CTAlertViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ - (void)showFromWindow:(BOOL)animated {
[self.window setHidden:NO];

void (^completionBlock)(void) = ^ {
if (self.delegate && [self.delegate respondsToSelector:@selector(notificationDidShow:fromViewController:)]) {
[self.delegate notificationDidShow:self.notification fromViewController:self];
if (self.delegate) {
[self.delegate notificationDidShow:self.notification];
}
};

Expand Down
4 changes: 2 additions & 2 deletions CleverTapSDK/InApps/CTBaseHeaderFooterViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,8 @@ - (void)showFromWindow:(BOOL)animated {
[self.window setHidden:NO];

void (^completionBlock)(void) = ^ {
if (self.delegate && [self.delegate respondsToSelector:@selector(notificationDidShow:fromViewController:)]) {
[self.delegate notificationDidShow:self.notification fromViewController:self];
if (self.delegate) {
[self.delegate notificationDidShow:self.notification];
}
};
if (animated) {
Expand Down
5 changes: 4 additions & 1 deletion CleverTapSDK/InApps/CTInAppDisplayManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#import "CTPushPrimerManager.h"
#import "CTInAppStore.h"
#import "CTInAppImagePrefetchManager.h"
#import "CTCustomTemplatesManager.h"

NS_ASSUME_NONNULL_BEGIN

Expand All @@ -36,11 +37,13 @@ typedef NS_ENUM(NSInteger, CleverTapInAppRenderingStatus) {
inAppFCManager:(CTInAppFCManager *)inAppFCManager
impressionManager:(CTImpressionManager *)impressionManager
inAppStore:(CTInAppStore *)inAppStore
imagePrefetchManager:(CTInAppImagePrefetchManager *)imagePrefetchManager;
imagePrefetchManager:(CTInAppImagePrefetchManager *)imagePrefetchManager
templatesManager:(CTCustomTemplatesManager *)templatesManager;

- (void)setPushPrimerManager:(CTPushPrimerManager* _Nonnull)pushPrimerManagerObj;
- (void)prepareNotificationForDisplay:(NSDictionary* _Nonnull)jsonObj;
- (BOOL)didHandleInAppTestFromPushNotificaton:(NSDictionary* _Nullable)notification;
- (BOOL)isTemplateRegistered:(NSDictionary *)inAppJSON;

- (void)_addInAppNotificationsToQueue:(NSArray *)inappNotifs;
- (void)_showNotificationIfAvailable;
Expand Down
Loading

0 comments on commit 29c2ba0

Please sign in to comment.