@@ -79,6 +79,10 @@ @interface OSInAppMessageViewController ()
7979// We start the timer once the message is displayed (not during loading the content)
8080@property (weak , nonatomic , nullable ) NSTimer *dismissalTimer;
8181
82+ // BOOL to track when an IAM has strated UI setup so we know when to bypass UI changes on dismissal or not
83+ // This is a fail safe for cases where global contraints are nil and we try to modify them on dismisal of an IAM
84+ @property (nonatomic ) BOOL didPageRenderingComplete;
85+
8286@end
8387
8488@implementation OSInAppMessageViewController
@@ -154,9 +158,6 @@ - (void)addAppEnterBackgroundObserver {
154158- (void )setupInitialMessageUI {
155159 [OneSignal onesignal_Log: ONE_S_LL_VERBOSE message: @" Setting up In-App Message" ];
156160
157- // Remove all of the constraints connected to the messageView
158- [self .messageView removeConstraints: [self .messageView constraints ]];
159-
160161 self.messageView .delegate = self;
161162
162163 [self .messageView setupWebViewConstraints ];
@@ -175,7 +176,7 @@ - (void)setupInitialMessageUI {
175176}
176177
177178- (void )displayMessage {
178- [OneSignal onesignal_Log: ONE_S_LL_VERBOSE message: @" Displaying In App Message" ];
179+ [OneSignal onesignal_Log: ONE_S_LL_VERBOSE message: @" Displaying In- App Message" ];
179180
180181 // Sets up the message view in a hidden position while we wait
181182 [self setupInitialMessageUI ];
@@ -231,9 +232,11 @@ - (void)loadMessageContent {
231232}
232233
233234- (void )loadPreviewMessageContent {
234- [self .message loadPreviewMessageHTMLContentWithUUID: self .message.messageId success: [self messageContentOnSuccess ] failure: ^(NSError *error) {
235- [self encounteredErrorLoadingMessageContent: error];
236- }];
235+ [self .message loadPreviewMessageHTMLContentWithUUID: self .message.messageId
236+ success: [self messageContentOnSuccess ]
237+ failure: ^(NSError *error) {
238+ [self encounteredErrorLoadingMessageContent: error];
239+ }];
237240}
238241
239242- (void )encounteredErrorLoadingMessageContent : (NSError * _Nullable)error {
@@ -392,47 +395,58 @@ Dismisses the message view with a given direction (up or down) and velocity
392395 */
393396- (void )dismissCurrentInAppMessage : (BOOL )up withVelocity : (double )velocity {
394397
395- // Inactivate the current Y constraints
396- self.finalYConstraint .active = false ;
397- self.initialYConstraint .active = false ;
398-
399- // The distance that the dismissal animation will travel
400- var distance = 0 .0f ;
401-
402- // Add new Y constraints
403- if (up) {
404- distance = self.messageView .frame .origin .y + self.messageView .frame .size .height + 8 .0f ;
405- [self .messageView.bottomAnchor constraintEqualToAnchor: self .view.topAnchor constant: -8 .0f ].active = true ;
406- } else {
407- distance = self.view .frame .size .height - self.messageView .frame .origin .y + 8 .0f ;
408- [self .messageView.topAnchor constraintEqualToAnchor: self .view.bottomAnchor constant: 8 .0f ].active = true ;
409- }
410-
411- var dismissAnimationDuration = velocity != 0 .0f ? distance / fabs (velocity) : 0 .3f ;
412-
413- var animationOption = UIViewAnimationOptionCurveLinear;
414-
415- // Impose a minimum animation speed (max duration)
416- if (dismissAnimationDuration > MAX_DISMISSAL_ANIMATION_DURATION) {
417- animationOption = UIViewAnimationOptionCurveEaseIn;
418- dismissAnimationDuration = MAX_DISMISSAL_ANIMATION_DURATION;
419- } else if (dismissAnimationDuration < MIN_DISMISSAL_ANIMATION_DURATION) {
420- animationOption = UIViewAnimationOptionCurveEaseIn;
421- dismissAnimationDuration = MIN_DISMISSAL_ANIMATION_DURATION;
422- }
398+ // Validate whether or not WebView actually rendered the IAM code, which we lead to global constraits not being nil
399+ if (self.didPageRenderingComplete ) {
400+
401+ // Inactivate the current Y constraints
402+ self.finalYConstraint .active = false ;
403+ self.initialYConstraint .active = false ;
404+
405+ // The distance that the dismissal animation will travel
406+ var distance = 0 .0f ;
407+
408+ // Add new Y constraints
409+ if (up) {
410+ distance = self.messageView .frame .origin .y + self.messageView .frame .size .height + 8 .0f ;
411+ [self .messageView.bottomAnchor constraintEqualToAnchor: self .view.topAnchor constant: -8 .0f ].active = true ;
412+ } else {
413+ distance = self.view .frame .size .height - self.messageView .frame .origin .y + 8 .0f ;
414+ [self .messageView.topAnchor constraintEqualToAnchor: self .view.bottomAnchor constant: 8 .0f ].active = true ;
415+ }
423416
424- [UIView animateWithDuration: dismissAnimationDuration delay: 0 .0f options: animationOption animations: ^{
425- self.view .backgroundColor = [UIColor clearColor ];
426- self.view .alpha = 0 .0f ;
427- [self .view layoutIfNeeded ];
428- } completion: ^(BOOL finished) {
429- if (!finished)
430- return ;
417+ var dismissAnimationDuration = velocity != 0 .0f ? distance / fabs (velocity) : 0 .3f ;
418+
419+ var animationOption = UIViewAnimationOptionCurveLinear;
420+
421+ // Impose a minimum animation speed (max duration)
422+ if (dismissAnimationDuration > MAX_DISMISSAL_ANIMATION_DURATION) {
423+ animationOption = UIViewAnimationOptionCurveEaseIn;
424+ dismissAnimationDuration = MAX_DISMISSAL_ANIMATION_DURATION;
425+ } else if (dismissAnimationDuration < MIN_DISMISSAL_ANIMATION_DURATION) {
426+ animationOption = UIViewAnimationOptionCurveEaseIn;
427+ dismissAnimationDuration = MIN_DISMISSAL_ANIMATION_DURATION;
428+ }
431429
432- [self dismissViewControllerAnimated: false completion: nil ];
430+ [UIView animateWithDuration: dismissAnimationDuration delay: 0 .0f options: animationOption animations: ^{
431+ self.view .backgroundColor = [UIColor clearColor ];
432+ self.view .alpha = 0 .0f ;
433+ [self .view layoutIfNeeded ];
434+ } completion: ^(BOOL finished) {
435+ if (!finished)
436+ return ;
437+
438+ [self dismissViewControllerAnimated: false completion: nil ];
439+
440+ self.didPageRenderingComplete = false ;
441+ [self .delegate messageViewControllerWasDismissed ];
442+ }];
443+ } else {
433444
445+ // If the rendering event never occurs any constraints being adjusted for dismissal will be nil
446+ // and we should bypass dismissal adjustments and animations and skip straight to the OSMessagingController callback for dismissing
447+ self.didPageRenderingComplete = false ;
434448 [self .delegate messageViewControllerWasDismissed ];
435- }];
449+ }
436450}
437451
438452/*
@@ -600,6 +614,10 @@ - (void)jsEventOccurredWithBody:(NSData *)body {
600614
601615 if (event) {
602616 if (event.type == OSInAppMessageBridgeEventTypePageRenderingComplete) {
617+
618+ // BOOL set to true since the JS event fired, meaning the WebView was populated properly with the IAM code
619+ self.didPageRenderingComplete = true ;
620+
603621 self.message .position = event.renderingComplete .displayLocation ;
604622 self.message .height = event.renderingComplete .height ;
605623
0 commit comments