Skip to content
This repository was archived by the owner on Jul 22, 2020. It is now read-only.

Commit 5839096

Browse files
authored
[In-Progress] Feature/itbl 2762 html in app notifcation (#40)
* In Progress: Initial changes for html in-app support * Calculates padding/offset for the in-app based upon the payload data. Handles the full screen layout. * Adds in additional logic for custom urls. Opens up any web http links by default. * Fixed up direct scheme check to avoid false positive schemes which contain http. * Updated api parsing for in-app Includes itbl:// custom scheme parsing Added background alpha level * Added in unit tests for location/padding calculation * updates to the tests for padding * More unit tests for padding * code cleanup * Updated params for get in-app to include optional platform / SDK version. * Update constants and html check for href tag * updated check to be case-insensitive * Removes automatic open of http/https urls.
1 parent 92199a6 commit 5839096

File tree

10 files changed

+705
-22
lines changed

10 files changed

+705
-22
lines changed

Iterable-iOS-SDK.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
09C0FC071A1D6D4700D5A86B /* libIterable-iOS-SDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 09C0FBFB1A1D6D4700D5A86B /* libIterable-iOS-SDK.a */; };
3434
09CCB9301D07A7EA003EB75D /* IterableNotificationMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 09CCB92F1D07A7EA003EB75D /* IterableNotificationMetadata.m */; };
3535
09CCB9321D07BA04003EB75D /* IterableNotificationMetadataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 09CCB9311D07BA04003EB75D /* IterableNotificationMetadataTests.m */; };
36+
1608832D1F83EED500318578 /* IterableInAppNotificationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1608832C1F83EED500318578 /* IterableInAppNotificationTests.m */; };
37+
160883301F840B5F00318578 /* IterableInAppHTMLViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1608832E1F840B5F00318578 /* IterableInAppHTMLViewController.h */; };
38+
160883311F840B5F00318578 /* IterableInAppHTMLViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1608832F1F840B5F00318578 /* IterableInAppHTMLViewController.m */; };
3639
16513DDE1D89EECC00C205B3 /* IterableInAppManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 16513DD81D89EECC00C205B3 /* IterableInAppManager.h */; };
3740
16513DDF1D89EECC00C205B3 /* IterableInAppManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 16513DD91D89EECC00C205B3 /* IterableInAppManager.m */; };
3841
1653A80E1D88B25200690298 /* IterableConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 1653A80B1D88B25200690298 /* IterableConstants.h */; };
@@ -90,6 +93,9 @@
9093
09CCB92F1D07A7EA003EB75D /* IterableNotificationMetadata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IterableNotificationMetadata.m; sourceTree = "<group>"; };
9194
09CCB9311D07BA04003EB75D /* IterableNotificationMetadataTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IterableNotificationMetadataTests.m; sourceTree = "<group>"; };
9295
15E14DC3FEF5EE94DFA2424E /* libPods-Iterable-iOS-SDKTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Iterable-iOS-SDKTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
96+
1608832C1F83EED500318578 /* IterableInAppNotificationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IterableInAppNotificationTests.m; sourceTree = "<group>"; };
97+
1608832E1F840B5F00318578 /* IterableInAppHTMLViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IterableInAppHTMLViewController.h; sourceTree = "<group>"; };
98+
1608832F1F840B5F00318578 /* IterableInAppHTMLViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IterableInAppHTMLViewController.m; sourceTree = "<group>"; };
9399
16513DD81D89EECC00C205B3 /* IterableInAppManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IterableInAppManager.h; sourceTree = "<group>"; };
94100
16513DD91D89EECC00C205B3 /* IterableInAppManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IterableInAppManager.m; sourceTree = "<group>"; };
95101
1653A80B1D88B25200690298 /* IterableConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IterableConstants.h; sourceTree = "<group>"; };
@@ -180,6 +186,7 @@
180186
091489E11CF6986900482D82 /* IterableAPITests.m */,
181187
091489E71CF6AC1800482D82 /* CommerceItemTests.m */,
182188
09CCB9311D07BA04003EB75D /* IterableNotificationMetadataTests.m */,
189+
1608832C1F83EED500318578 /* IterableInAppNotificationTests.m */,
183190
);
184191
path = "Iterable-iOS-SDKTests";
185192
sourceTree = "<group>";
@@ -195,6 +202,8 @@
195202
16CE7A051DF8D5A900CADC2D /* InAppNotifications */ = {
196203
isa = PBXGroup;
197204
children = (
205+
1608832E1F840B5F00318578 /* IterableInAppHTMLViewController.h */,
206+
1608832F1F840B5F00318578 /* IterableInAppHTMLViewController.m */,
198207
16513DD81D89EECC00C205B3 /* IterableInAppManager.h */,
199208
16513DD91D89EECC00C205B3 /* IterableInAppManager.m */,
200209
16ED2E461D90569500ADCAEC /* IterableInAppBaseViewController.h */,
@@ -247,6 +256,7 @@
247256
093028D31D1B958700E7CFBE /* IterableLogging.h in Headers */,
248257
16ED2E4F1D908D5500ADCAEC /* IterableAlertViewController.h in Headers */,
249258
16513DDE1D89EECC00C205B3 /* IterableInAppManager.h in Headers */,
259+
160883301F840B5F00318578 /* IterableInAppHTMLViewController.h in Headers */,
250260
);
251261
runOnlyForDeploymentPostprocessing = 0;
252262
};
@@ -462,6 +472,7 @@
462472
16ED2E501D908D5500ADCAEC /* IterableAlertViewController.m in Sources */,
463473
093734271A1D701F00C950B6 /* IterableAPI.m in Sources */,
464474
1653A8101D88B25200690298 /* IterableFullScreenViewController.m in Sources */,
475+
160883311F840B5F00318578 /* IterableInAppHTMLViewController.m in Sources */,
465476
6804B8601AC0F363000A126B /* CommerceItem.m in Sources */,
466477
16E02BAD1E035EA400644C15 /* IterableConstants.m in Sources */,
467478
0995DBDD1CFFF7FE00D50F19 /* IterableLogging.m in Sources */,
@@ -474,6 +485,7 @@
474485
files = (
475486
091489E21CF6986900482D82 /* IterableAPITests.m in Sources */,
476487
09CCB9321D07BA04003EB75D /* IterableNotificationMetadataTests.m in Sources */,
488+
1608832D1F83EED500318578 /* IterableInAppNotificationTests.m in Sources */,
477489
091489E81CF6AC1800482D82 /* CommerceItemTests.m in Sources */,
478490
);
479491
runOnlyForDeploymentPostprocessing = 0;

Iterable-iOS-SDK/IterableAPI.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,16 @@ typedef NS_ENUM(NSInteger, PushServicePlatform) {
502502
*/
503503
- (void)trackInAppClick:(NSString *)messageId buttonIndex:(NSNumber *)buttonIndex;
504504

505+
/**
506+
@method
507+
508+
@abstract Tracks a inAppClick event
509+
510+
@param messageId The messageId of the notification
511+
@param buttonURL The url of the button that was clicked
512+
*/
513+
- (void)trackInAppClick:(NSString *)messageId buttonURL:(NSString *)buttonURL;
514+
505515
/**
506516
@method
507517

Iterable-iOS-SDK/IterableAPI.m

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,26 @@ - (void)trackInAppClick:(NSString *)messageId buttonIndex:(NSNumber*)buttonIndex
532532
[self sendRequest:request onSuccess:[IterableAPI defaultOnSuccess:@"trackInAppClick"] onFailure:[IterableAPI defaultOnFailure:@"trackInAppClick"]];
533533
}
534534

535+
// documented in IterableAPI.h
536+
- (void)trackInAppClick:(NSString *)messageId buttonURL:(NSString*)buttonURL {
537+
NSDictionary *args;
538+
if (_email != nil) {
539+
args = @{
540+
ITBL_KEY_EMAIL: self.email,
541+
ITBL_KEY_MESSAGE_ID: messageId,
542+
ITERABLE_IN_APP_CLICK_URL: buttonURL
543+
};
544+
} else {
545+
args = @{
546+
ITBL_KEY_USER_ID: self.userId,
547+
ITBL_KEY_MESSAGE_ID: messageId,
548+
ITERABLE_IN_APP_CLICK_URL: buttonURL
549+
};
550+
}
551+
NSURLRequest *request = [self createRequestForAction:ENDPOINT_TRACK_INAPP_CLICK withArgs:args];
552+
[self sendRequest:request onSuccess:[IterableAPI defaultOnSuccess:@"trackInAppClick"] onFailure:[IterableAPI defaultOnFailure:@"trackInAppClick"]];
553+
}
554+
535555
// documented in IterableAPI.h
536556
- (void)registerToken:(NSData *)token appName:(NSString *)appName pushServicePlatform:(PushServicePlatform)pushServicePlatform
537557
{
@@ -846,23 +866,33 @@ - (void)spawnInAppNotification:(ITEActionBlock)callbackBlock
846866
OnSuccessHandler onSuccess = ^(NSDictionary* payload) {
847867
NSDictionary *dialogOptions = [IterableInAppManager getNextMessageFromPayload:payload];
848868
if (dialogOptions != nil) {
849-
NSDictionary *message = [dialogOptions valueForKeyPath:ITERABLE_IN_APP_CONTENT];
850-
NSString *messageId = [dialogOptions valueForKey:ITBL_KEY_MESSAGE_ID];
851-
852-
[self trackInAppOpen:messageId];
853-
[self inAppConsume:messageId];
854-
IterableNotificationMetadata *notification = [IterableNotificationMetadata metadataFromInAppOptions:messageId];
855-
869+
NSDictionary *message = [dialogOptions valueForKey:ITERABLE_IN_APP_CONTENT];
856870
if (message != nil) {
857-
dispatch_sync(dispatch_get_main_queue(), ^{
858-
[IterableInAppManager showIterableNotification:message trackParams:notification callbackBlock:(ITEActionBlock)callbackBlock];
859-
});
871+
NSString *messageId = [dialogOptions valueForKey:ITBL_KEY_MESSAGE_ID];
872+
NSString *html = [message objectForKey:ITERABLE_IN_APP_HTML];
873+
874+
//uses the rangeOfString check for backwards compatability with iOS7
875+
if (html != nil && !([html rangeOfString:ITERABLE_IN_APP_HREF options:NSCaseInsensitiveSearch].location == NSNotFound)) {
876+
NSDictionary *inAppDisplaySettings = [message valueForKey:ITERABLE_IN_APP_DISPLAY_SETTINGS];
877+
double backgroundAlpha = [[inAppDisplaySettings valueForKey:ITERABLE_IN_APP_BACKGROUND_ALPHA] doubleValue];
878+
UIEdgeInsets edgeInsets = [IterableInAppManager getPaddingFromPayload:inAppDisplaySettings];
879+
880+
IterableNotificationMetadata *notification = [IterableNotificationMetadata metadataFromInAppOptions:messageId];
881+
882+
dispatch_sync(dispatch_get_main_queue(), ^{
883+
[IterableInAppManager showIterableNotificationHTML:html trackParams:(IterableNotificationMetadata*)notification callbackBlock:(ITEActionBlock)callbackBlock backgroundAlpha:backgroundAlpha padding:edgeInsets];
884+
});
885+
} else {
886+
LogWarning(@"No href tag found in the in-app html payload: %@", html);
887+
}
888+
889+
[self inAppConsume:messageId];
860890
}
861891
} else {
862892
LogDebug(@"No notifications found for inApp payload %@", payload);
863893
}
864894
};
865-
895+
866896
[self getInAppMessages:@1 onSuccess:onSuccess onFailure:[IterableAPI defaultOnFailure:@"getInAppMessages"]];
867897
}
868898

@@ -879,12 +909,16 @@ - (void)getInAppMessages:(NSNumber *)count onSuccess:(OnSuccessHandler)onSuccess
879909
if (_email != nil) {
880910
args = @{
881911
ITBL_KEY_EMAIL: self.email,
882-
ITBL_KEY_COUNT: count
912+
ITBL_KEY_COUNT: count,
913+
ITBL_KEY_PLATFORM: ITBL_PLATFORM_IOS,
914+
ITBL_KEY_SDK_VERSION: @"0.0.0"
883915
};
884916
} else {
885917
args = @{
886918
ITBL_KEY_USER_ID: self.userId,
887-
ITBL_KEY_COUNT: count
919+
ITBL_KEY_COUNT: count,
920+
ITBL_KEY_PLATFORM: ITBL_PLATFORM_IOS,
921+
ITBL_KEY_SDK_VERSION: @"0.0.0"
888922
};
889923
}
890924
NSURLRequest *request = [self createGetRequestForAction:ENDPOINT_GET_INAPP_MESSAGES withArgs:args];

Iterable-iOS-SDK/IterableConstants.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ extern NSString *const ITBL_KEY_MESSAGE_ID;
2424
extern NSString *const ITBL_KEY_NEW_EMAIL;
2525
extern NSString *const ITBL_KEY_PLATFORM;
2626
extern NSString *const ITBL_KEY_RECIPIENT_EMAIL;
27+
extern NSString *const ITBL_KEY_SDK_VERSION;
2728
extern NSString *const ITBL_KEY_SEND_AT;
2829
extern NSString *const ITBL_KEY_TOKEN;
2930
extern NSString *const ITBL_KEY_TEMPLATE_ID;
@@ -65,11 +66,15 @@ extern NSString *const ITBL_DEVICE_USER_INTERFACE;
6566
#define ITBL_KEY_PHONE @"Phone"
6667
#define ITBL_KEY_UNSPECIFIED @"Unspecified"
6768

69+
#define ITBL_PLATFORM_IOS @"iOS"
70+
6871

6972
#define ITBL_DEEPLINK_IDENTIFIER @"/a/[a-zA-Z0-9]+"
7073

7174

7275
//In-App Constants
76+
#define ITERABLE_IN_APP_CLICK_URL @"urlClick"
77+
7378
#define ITERABLE_IN_APP_TITLE @"title"
7479
#define ITERABLE_IN_APP_BODY @"body"
7580
#define ITERABLE_IN_APP_IMAGE @"mainImage"
@@ -90,5 +95,11 @@ extern NSString *const ITBL_DEVICE_USER_INTERFACE;
9095
#define ITERABLE_IN_APP_BUTTON_ACTION @"action"
9196
#define ITERABLE_IN_APP_CONTENT @"content"
9297

98+
//In-App HTML Constants
99+
#define ITERABLE_IN_APP_BACKGROUND_ALPHA @"backgroundAlpha"
100+
#define ITERABLE_IN_APP_HTML @"html"
101+
#define ITERABLE_IN_APP_HREF @"href"
102+
#define ITERABLE_IN_APP_DISPLAY_SETTINGS @"inAppDisplaySettings"
103+
93104

94105
typedef void (^ITEActionBlock)(NSString *);

Iterable-iOS-SDK/IterableConstants.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ @implementation IterableConstants : NSObject
2020
NSString *const ITBL_KEY_DEVICE = @"device";
2121
NSString *const ITBL_KEY_EMAIL = @"email";
2222
NSString *const ITBL_KEY_EVENT_NAME = @"eventName";
23+
NSString *const ITBL_KEY_INAPP_DISPLAY = @"inAppDisplaySettings";
2324
NSString *const ITBL_KEY_ITEMS = @"items";
2425
NSString *const ITBL_KEY_MERGE_NESTED = @"mergeNestedObjects";
2526
NSString *const ITBL_KEY_MESSAGE_ID = @"messageId";
2627
NSString *const ITBL_KEY_NEW_EMAIL = @"newEmail";
2728
NSString *const ITBL_KEY_PLATFORM = @"platform";
2829
NSString *const ITBL_KEY_RECIPIENT_EMAIL = @"recipientEmail";
30+
NSString *const ITBL_KEY_SDK_VERSION = @"SDKVersion";
2931
NSString *const ITBL_KEY_SEND_AT = @"sendAt";
3032
NSString *const ITBL_KEY_TOKEN = @"token";
3133
NSString *const ITBL_KEY_TEMPLATE_ID = @"templateId";
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//
2+
// IterableInAppHTMLViewController.h
3+
// Pods
4+
//
5+
// Created by David Truong on 9/8/17.
6+
//
7+
//
8+
9+
#import <UIKit/UIKit.h>
10+
#import "IterableConstants.h"
11+
#import "IterableNotificationMetadata.h"
12+
13+
@interface IterableInAppHTMLViewController : UIViewController
14+
15+
/**
16+
@abstract Custom ITEActionBlock
17+
*/
18+
typedef void (^ITEActionBlock)(NSString *);
19+
20+
typedef enum {
21+
INAPP_FULL,
22+
INAPP_TOP,
23+
INAPP_CENTER,
24+
INAPP_BOTTOM
25+
} INAPP_NOTIFICATION_TYPE;
26+
27+
/**
28+
@method
29+
30+
@abstract constructs an inapp notification with via html
31+
32+
@param htmlString the html string
33+
*/
34+
- (IterableInAppHTMLViewController*)initWithData:htmlString;
35+
36+
/**
37+
@method
38+
39+
@abstract Sets the padding
40+
41+
@param insetPadding the padding
42+
43+
@discussion defaults to 0 for left/right if left+right >100
44+
*/
45+
-(void)ITESetPadding:(UIEdgeInsets)insetPadding;
46+
47+
/**
48+
@method
49+
50+
@abstract Sets the callback
51+
52+
@param callbackBlock the payload data
53+
*/
54+
-(void)ITESetCallback:(ITEActionBlock)callbackBlock;
55+
56+
/**
57+
@method
58+
59+
@abstract Sets the track parameters
60+
61+
@param trackParams the track parameters
62+
*/
63+
-(void)ITESetTrackParams:(IterableNotificationMetadata *)trackParams;
64+
65+
/**
66+
@method
67+
68+
@abstract gets the html string
69+
70+
@return a NSString of the html
71+
*/
72+
-(NSString *)getHtml;
73+
74+
/**
75+
@method
76+
77+
@abstract gets the location from a inset data
78+
79+
@return the location as an INAPP_NOTIFICATION_TYPE
80+
*/
81+
+(INAPP_NOTIFICATION_TYPE)setLocation:(UIEdgeInsets) insetPadding;
82+
83+
@end

0 commit comments

Comments
 (0)