Skip to content

Commit e468cc3

Browse files
authored
Merge pull request #1018 from OneSignal/feature/Fullbleed_IAM
Fullbleed In App Messages
2 parents cd360b1 + d705397 commit e468cc3

File tree

4 files changed

+119
-42
lines changed

4 files changed

+119
-42
lines changed

iOS_SDK/OneSignalSDK/Source/OSInAppMessageView.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@ NS_ASSUME_NONNULL_BEGIN
4444

4545
- (instancetype _Nonnull)initWithMessage:(OSInAppMessageInternal *)inAppMessage withScriptMessageHandler:(id<WKScriptMessageHandler>)messageHandler;
4646
- (void)resetWebViewToMaxBoundsAndResizeHeight:(void (^) (NSNumber *newHeight)) completion;
47+
- (void)updateSafeAreaInsets;
4748
- (void)setupWebViewConstraints;
4849
- (void)loadReplacementURL:(NSURL *)url;
4950
- (void)loadedHtmlContent:(NSString *)html withBaseURL:(NSURL *)url;
5051
- (void)removeScriptMessageHandler;
51-
52+
- (void)setIsFullscreen:(BOOL)isFullscreen;
5253
@end
5354

5455
NS_ASSUME_NONNULL_END

iOS_SDK/OneSignalSDK/Source/OSInAppMessageView.m

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ @interface OSInAppMessageView () <UIScrollViewDelegate, WKUIDelegate, WKNavigati
3838
@property (strong, nonatomic, nonnull) OSInAppMessageInternal *message;
3939
@property (strong, nonatomic, nonnull) WKWebView *webView;
4040
@property (nonatomic) BOOL loaded;
41-
41+
@property (nonatomic) BOOL isFullscreen;
4242
@end
4343

4444

@@ -89,13 +89,10 @@ - (NSString *)addTagsToHTML:(NSString *)html {
8989

9090
- (void)loadedHtmlContent:(NSString *)html withBaseURL:(NSURL *)url {
9191
// UI Update must be done on the main thread
92-
NSLog(@"11111 [self.webView loadHTMLString:html baseURL:url];");
93-
dispatch_sync(dispatch_get_main_queue(), ^{
94-
NSLog(@"222222 [self.webView loadHTMLString:html baseURL:url];");
95-
NSString *taggedHTML = [self addTagsToHTML:html];
96-
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"loadedHtmlContent with Tags: \n%@", taggedHTML]];
97-
[self.webView loadHTMLString:taggedHTML baseURL:url];
98-
});
92+
NSString *taggedHTML = [self addTagsToHTML:html];
93+
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"loadedHtmlContent with Tags: \n%@", taggedHTML]];
94+
[self.webView loadHTMLString:taggedHTML baseURL:url];
95+
9996
}
10097

10198
- (void)setupWebviewWithMessageHandler:(id<WKScriptMessageHandler>)handler {
@@ -118,6 +115,20 @@ - (void)setupWebviewWithMessageHandler:(id<WKScriptMessageHandler>)handler {
118115
[self layoutIfNeeded];
119116
}
120117

118+
- (void)setIsFullscreen:(BOOL)isFullscreen {
119+
_isFullscreen = isFullscreen;
120+
[self setWebviewFrame];
121+
}
122+
123+
- (void)setWebviewFrame {
124+
CGRect mainBounds = UIScreen.mainScreen.bounds;
125+
if (!self.isFullscreen) {
126+
CGFloat marginSpacing = [OneSignalViewHelper sizeToScale:MESSAGE_MARGIN];
127+
mainBounds.size.width -= (2.0 * marginSpacing);
128+
}
129+
[self.webView setFrame:mainBounds];
130+
}
131+
121132
/*
122133
Method for resetting the height of the WebView so the JS can calculate the new height
123134
WebView will have margins accounted for on width, but height just needs to be phone height or larger
@@ -126,11 +137,8 @@ - (void)setupWebviewWithMessageHandler:(id<WKScriptMessageHandler>)handler {
126137
- (void)resetWebViewToMaxBoundsAndResizeHeight:(void (^) (NSNumber *newHeight)) completion {
127138
[self.webView removeConstraints:[self.webView constraints]];
128139

129-
CGFloat marginSpacing = [OneSignalViewHelper sizeToScale:MESSAGE_MARGIN];
130-
CGRect mainBounds = UIScreen.mainScreen.bounds;
131-
mainBounds.size.width -= (2.0 * marginSpacing);
132-
133-
[self.webView setFrame:mainBounds];
140+
141+
[self setWebviewFrame];
134142
[self.webView layoutIfNeeded];
135143

136144
// Evaluate JS getPageMetaData() method to obtain the updated height for the messageView to contain the webView contents
@@ -151,6 +159,28 @@ - (void)resetWebViewToMaxBoundsAndResizeHeight:(void (^) (NSNumber *newHeight))
151159
}];
152160
}
153161

162+
- (void)updateSafeAreaInsets {
163+
if (@available(iOS 11, *)) {
164+
UIWindow *keyWindow = UIApplication.sharedApplication.keyWindow;
165+
CGFloat top = keyWindow.safeAreaInsets.top;
166+
CGFloat bottom = keyWindow.safeAreaInsets.bottom;
167+
CGFloat right = keyWindow.safeAreaInsets.right;
168+
CGFloat left = keyWindow.safeAreaInsets.left;
169+
NSString *safeAreaInsetsObjectString = [NSString stringWithFormat:OS_JS_SAFE_AREA_INSETS_OBJ,top, bottom, right, left];
170+
171+
NSString *setInsetsString = [NSString stringWithFormat:OS_SET_SAFE_AREA_INSETS_METHOD, safeAreaInsetsObjectString];
172+
[self.webView evaluateJavaScript:setInsetsString completionHandler:^(NSDictionary *result, NSError * _Nullable error) {
173+
if (error) {
174+
NSString *errorMessage = [NSString stringWithFormat:@"Javascript Method: %@ Evaluated with Error: %@", OS_SET_SAFE_AREA_INSETS_METHOD, error];
175+
[OneSignal onesignal_Log:ONE_S_LL_ERROR message:errorMessage];
176+
return;
177+
}
178+
NSString *successMessage = [NSString stringWithFormat:@"Javascript Method: %@ Evaluated with Success: %@", OS_SET_SAFE_AREA_INSETS_METHOD, result];
179+
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:successMessage];
180+
}];
181+
}
182+
}
183+
154184
- (NSNumber *)extractHeightFromMetaDataPayload:(NSDictionary *)result {
155185
return @([result[@"rect"][@"height"] intValue]);
156186
}

iOS_SDK/OneSignalSDK/Source/OSInAppMessageViewController.m

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ @interface OSInAppMessageViewController ()
9797

9898
@property (nonatomic) BOOL useWidthMargin;
9999

100+
@property (nonatomic) BOOL isFullscreen;
101+
100102
@end
101103

102104
@implementation OSInAppMessageViewController
@@ -225,25 +227,27 @@ - (void)maxDisplayTimeTimerFinished {
225227

226228
- (OSResultSuccessBlock)messageContentOnSuccess {
227229
return ^(NSDictionary *data) {
228-
if (!data) {
229-
[self encounteredErrorLoadingMessageContent:nil];
230-
return;
231-
}
232-
233-
let message = [NSString stringWithFormat:@"In App Messaging htmlContent.html: %@", data[@"html"]];
234-
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:message];
235-
236-
if (!self.message.isPreview)
237-
[[OneSignal sessionManager] onInAppMessageReceived:self.message.messageId];
230+
[OneSignalHelper dispatch_async_on_main_queue:^{
231+
if (!data) {
232+
[self encounteredErrorLoadingMessageContent:nil];
233+
return;
234+
}
235+
236+
let message = [NSString stringWithFormat:@"In App Messaging htmlContent.html: %@", data[@"html"]];
237+
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:message];
238+
239+
if (!self.message.isPreview)
240+
[[OneSignal sessionManager] onInAppMessageReceived:self.message.messageId];
238241

239-
let baseUrl = [NSURL URLWithString:OS_IAM_WEBVIEW_BASE_URL];
240-
[self parseContentData:data];
241-
if (self.waitForTags) {
242-
return;
243-
}
244-
[self.delegate messageWillDisplay:self.message];
245-
[self.messageView loadedHtmlContent:self.pendingHTMLContent withBaseURL:baseUrl];
246-
self.pendingHTMLContent = nil;
242+
let baseUrl = [NSURL URLWithString:OS_IAM_WEBVIEW_BASE_URL];
243+
[self parseContentData:data];
244+
if (self.waitForTags) {
245+
return;
246+
}
247+
[self.delegate messageWillDisplay:self.message];
248+
[self.messageView loadedHtmlContent:self.pendingHTMLContent withBaseURL:baseUrl];
249+
self.pendingHTMLContent = nil;
250+
}];
247251
};
248252
}
249253

@@ -261,6 +265,32 @@ - (void)parseContentData:(NSDictionary *)data {
261265
self.useWidthMargin = ![styles[@"remove_width_margin"] boolValue];
262266
}
263267
}
268+
self.isFullscreen = !self.useHeightMargin;
269+
if (self.isFullscreen) {
270+
self.pendingHTMLContent = [self setContentInsetsInHTML:self.pendingHTMLContent];
271+
}
272+
[self.messageView setIsFullscreen:self.isFullscreen];
273+
}
274+
275+
- (NSString *)setContentInsetsInHTML:(NSString *)html {
276+
NSMutableString *newHTML = [[NSMutableString alloc] initWithString:html];
277+
if (@available(iOS 11, *)) {
278+
UIWindow *keyWindow = UIApplication.sharedApplication.keyWindow;
279+
if (!keyWindow) {
280+
return newHTML;
281+
}
282+
CGFloat top = keyWindow.safeAreaInsets.top;
283+
CGFloat bottom = keyWindow.safeAreaInsets.bottom;
284+
CGFloat right = keyWindow.safeAreaInsets.right;
285+
CGFloat left = keyWindow.safeAreaInsets.left;
286+
NSString *safeAreaInsetsObjectString = [NSString stringWithFormat:OS_JS_SAFE_AREA_INSETS_OBJ,top, bottom, right, left];
287+
NSString *insetsString = [NSString stringWithFormat:@"\n\n\
288+
<script> \
289+
setSafeAreaInsets(%@);\
290+
</script>",safeAreaInsetsObjectString];
291+
[newHTML appendString: insetsString];
292+
}
293+
return newHTML;
264294
}
265295

266296
- (void)setWaitForTags:(BOOL)waitForTags {
@@ -318,13 +348,15 @@ - (void)addConstraintsForMessage {
318348
// as a notch or a rounded corner on newer iOS devices like iPhone X
319349
// Note that Safe Area layout guides were only introduced in iOS 11
320350
if (@available(iOS 11, *)) {
321-
let safeArea = self.view.safeAreaLayoutGuide;
322-
top = safeArea.topAnchor;
323-
bottom = safeArea.bottomAnchor;
324-
leading = safeArea.leadingAnchor;
325-
trailing = safeArea.trailingAnchor;
326-
center = safeArea.centerXAnchor;
327-
height = safeArea.heightAnchor;
351+
if (!self.isFullscreen) {
352+
let safeArea = self.view.safeAreaLayoutGuide;
353+
top = safeArea.topAnchor;
354+
bottom = safeArea.bottomAnchor;
355+
leading = safeArea.leadingAnchor;
356+
trailing = safeArea.trailingAnchor;
357+
center = safeArea.centerXAnchor;
358+
height = safeArea.heightAnchor;
359+
}
328360
}
329361

330362
CGRect mainBounds = [OneSignalViewHelper getScreenBounds];
@@ -400,8 +432,10 @@ - (void)addConstraintsForMessage {
400432
self.view.window.frame = mainBounds;
401433
NSLayoutAnchor *centerYanchor = self.view.centerYAnchor;
402434
if (@available(iOS 11, *)) {
403-
let safeArea = self.view.safeAreaLayoutGuide;
404-
centerYanchor = safeArea.centerYAnchor;
435+
if (!self.isFullscreen) {
436+
let safeArea = self.view.safeAreaLayoutGuide;
437+
centerYanchor = safeArea.centerYAnchor;
438+
}
405439
}
406440

407441
self.initialYConstraint = [self.messageView.centerYAnchor constraintEqualToAnchor:centerYanchor constant:0.0f];
@@ -699,8 +733,12 @@ - (void)jsEventOccurredWithBody:(NSData *)body {
699733
break;
700734
}
701735
case OSInAppMessageBridgeEventTypePageResize: {
702-
// Unused resize event for IAM during actions like orientation changes and displaying an IAM
736+
// resize event for IAM during actions like orientation changes and displaying an IAM
737+
// Currently used for fullscreen IAMs to account for safe area changes
703738
// self.message.height = event.resize.height;
739+
if (self.isFullscreen) {
740+
[self.messageView updateSafeAreaInsets];
741+
}
704742
break;
705743
}
706744
case OSInAppMessageBridgeEventTypeActionTaken: {

iOS_SDK/OneSignalSDK/Source/OSInAppMessagingDefines.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,16 @@ typedef NS_ENUM(NSUInteger, OSTriggerOperatorType) {
9292
// Verify that a string is a valid dynamic trigger
9393
#define OS_IS_TRIGGER_PROPERTY(kind) [OS_TRIGGER_PROPERTY_STRINGS containsObject:property]
9494

95+
// Javascript object
96+
#define OS_JS_SAFE_AREA_INSETS_OBJ @"{\n\
97+
top: %f,\n\
98+
bottom: %f,\n\
99+
right: %f,\n\
100+
left: %f,\n\
101+
}"
95102
// JavaScript method names
96103
#define OS_JS_GET_PAGE_META_DATA_METHOD @"getPageMetaData()"
104+
#define OS_SET_SAFE_AREA_INSETS_METHOD @"setSafeAreaInsets(%@)"
97105

98106
#define PREFERRED_VARIANT_ORDER @[@"ios", @"app", @"all"]
99107

0 commit comments

Comments
 (0)