diff --git a/Example/Example.xcodeproj/project.xcworkspace/xcuserdata/lukas.xcuserdatad/UserInterfaceState.xcuserstate b/Example/Example.xcodeproj/project.xcworkspace/xcuserdata/lukas.xcuserdatad/UserInterfaceState.xcuserstate index d327cb0..5d82b71 100644 Binary files a/Example/Example.xcodeproj/project.xcworkspace/xcuserdata/lukas.xcuserdatad/UserInterfaceState.xcuserstate and b/Example/Example.xcodeproj/project.xcworkspace/xcuserdata/lukas.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Example/Example/AppDelegate.swift b/Example/Example/AppDelegate.swift index 2719986..1ed29ff 100644 --- a/Example/Example/AppDelegate.swift +++ b/Example/Example/AppDelegate.swift @@ -18,7 +18,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, GleapDelegate { //Gleap.setApiUrl("http://0.0.0.0:9000") //Gleap.setFrameUrl("http://0.0.0.0:3001/appnew.html") - Gleap.initialize(withToken: "ogWhNhuiZcGWrva5nlDS8l7a78OfaLlV") + Gleap.initialize(withToken: "gbMLfLgtayFd2PeNJrjbxl6eB2OboAfn") Gleap.sharedInstance().delegate = self diff --git a/Gleap.podspec b/Gleap.podspec index 0955ad4..543b61c 100644 --- a/Gleap.podspec +++ b/Gleap.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = "Gleap" - s.version = "14.0.2" + s.version = "14.0.3" s.summary = "In-App Bug Reporting and Testing for Apps. Learn more at https://gleap.io" s.homepage = "https://gleap.io" s.license = { :type => 'Commercial', :file => 'LICENSE.md' } diff --git a/Sources/ObjCSources/GleapCore.h b/Sources/ObjCSources/GleapCore.h index 14a97c4..06e288a 100755 --- a/Sources/ObjCSources/GleapCore.h +++ b/Sources/ObjCSources/GleapCore.h @@ -81,6 +81,14 @@ typedef enum surveyFormat { SURVEY, SURVEY_FULL } GleapSurveyFormat; + (void)openNews; + (void)openNews:(Boolean)showBackButton; +/** + * Sets an y offset for the notification view when the feedback button is set to hidden (either through the config or code overwrite). + * @author Gleap + * + * @param offsetY The Y offset of the notification view. + */ ++ (void)setNotificationViewOffsetY: (int)offsetY; + /** * Open the checklists overview. * @author Gleap @@ -543,6 +551,7 @@ typedef enum surveyFormat { SURVEY, SURVEY_FULL } GleapSurveyFormat; @property (nonatomic, retain) NSArray* blacklist; @property (nonatomic, retain) NSArray *networkLogPropsToIgnore; @property (nonatomic, assign) int initialized; +@property (nonatomic, assign) int notificationViewOffsetY; @property (nonatomic, assign) GleapApplicationType applicationType; @property (nonatomic, weak) id delegate; diff --git a/Sources/ObjCSources/GleapCore.m b/Sources/ObjCSources/GleapCore.m index c91370a..8556dba 100755 --- a/Sources/ObjCSources/GleapCore.m +++ b/Sources/ObjCSources/GleapCore.m @@ -75,6 +75,7 @@ - (void)initHelper { self.blacklist = [[NSArray alloc] init]; self.networkLogPropsToIgnore = [[NSArray alloc] init]; self.initialized = NO; + self.notificationViewOffsetY = 20; self.applicationType = NATIVE; [[GleapMetaDataHelper sharedInstance] startSession]; @@ -88,6 +89,10 @@ + (void)setAutoActivationMethodsDisabled { [GleapActivationMethodHelper setAutoActivationMethodsDisabled]; } ++ (void)setNotificationViewOffsetY: (int)offsetY { + [Gleap sharedInstance].notificationViewOffsetY = offsetY; +} + + (void)setLanguage: (NSString *)language { [GleapTranslationHelper setLanguage: language]; } diff --git a/Sources/ObjCSources/GleapFeedbackButton.h b/Sources/ObjCSources/GleapFeedbackButton.h index 78510a5..fbfe52e 100644 --- a/Sources/ObjCSources/GleapFeedbackButton.h +++ b/Sources/ObjCSources/GleapFeedbackButton.h @@ -26,7 +26,6 @@ NS_ASSUME_NONNULL_BEGIN @property (strong, nonatomic) NSLayoutConstraint *safeAreaConstraint; @property (strong, nonatomic) NSLayoutConstraint *edgeConstraint; - @end NS_ASSUME_NONNULL_END diff --git a/Sources/ObjCSources/GleapFeedbackButton.m b/Sources/ObjCSources/GleapFeedbackButton.m index 5160ca9..246eb7e 100644 --- a/Sources/ObjCSources/GleapFeedbackButton.m +++ b/Sources/ObjCSources/GleapFeedbackButton.m @@ -215,7 +215,7 @@ - (void)setupClassicButton { if (@available(iOS 11, *)) { UILayoutGuide *guide = window.safeAreaLayoutGuide; - _safeAreaConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:guide attribute:NSLayoutAttributeLeading multiplier:1 constant: -(buttonHeight - 6)]; + _safeAreaConstraint = [NSLayoutConstraint constraintWithItem: self attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem: guide attribute:NSLayoutAttributeLeading multiplier:1 constant: -(buttonHeight - 6)]; } } else if ([feedbackButtonPosition isEqualToString: @"BUTTON_CLASSIC_BOTTOM"]) { rotation = 0; @@ -388,15 +388,15 @@ - (void)updateConstraintsForOrientation { NSMutableArray *toDeactivate = [NSMutableArray array]; if (shouldActivateSafeAreaConstraint) { - [toActivate addObject:self.safeAreaConstraint]; + [toActivate addObject: self.safeAreaConstraint]; } else { - [toDeactivate addObject:self.safeAreaConstraint]; + [toDeactivate addObject: self.safeAreaConstraint]; } if (shouldActivateEdgeConstraint) { - [toActivate addObject:self.edgeConstraint]; + [toActivate addObject: self.edgeConstraint]; } else { - [toDeactivate addObject:self.edgeConstraint]; + [toDeactivate addObject: self.edgeConstraint]; } // Deactivate constraints safely @@ -406,45 +406,13 @@ - (void)updateConstraintsForOrientation { // Activate constraints safely if (toActivate.count > 0) { - [NSLayoutConstraint activateConstraints:toActivate]; + [NSLayoutConstraint activateConstraints: toActivate]; } } @catch (NSException *exception) { // Handle exceptions if necessary } } -- (void)safelyActivateConstraints:(NSArray *)constraints { - for (NSLayoutConstraint *constraint in constraints) { - if (constraint == nil) { - NSLog(@"Gleap: Attempted to activate a nil constraint."); - continue; - } - - if (constraint.firstItem == nil || constraint.secondItem == nil) { - NSLog(@"Gleap: Constraint has nil items: %@", constraint); - continue; - } - - UIView *firstView = [constraint.firstItem isKindOfClass:[UIView class]] ? (UIView *)constraint.firstItem : nil; - if (firstView && ![firstView isDescendantOfView: self]) { - NSLog(@"Gleap: First item of constraint is not in the view hierarchy: %@", constraint); - continue; - } - - UIView *secondView = [constraint.secondItem isKindOfClass:[UIView class]] ? (UIView *)constraint.secondItem : nil; - if (secondView && ![secondView isDescendantOfView: self]) { - NSLog(@"Gleap: Second item of constraint is not in the view hierarchy: %@", constraint); - continue; - } - - @try { - [NSLayoutConstraint activateConstraints:@[constraint]]; - } @catch (NSException *exception) { - NSLog(@"Gleap: Exception activating constraint: %@, Exception: %@", constraint, exception); - } - } -} - - (void)setupModernButton { @try { NSDictionary *config = GleapConfigHelper.sharedInstance.config; @@ -518,8 +486,20 @@ - (void)setupModernButton { } } +- (void)willMoveToSuperview:(UIView *)newSuperview { + if (!newSuperview) { + @try { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; + } @catch (NSException *exception) {} + } + + [super willMoveToSuperview:newSuperview]; +} + - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; + @try { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; + } @catch (NSException *exception) {} } @end diff --git a/Sources/ObjCSources/GleapMetaDataHelper.h b/Sources/ObjCSources/GleapMetaDataHelper.h index 96c78e6..3325ab0 100644 --- a/Sources/ObjCSources/GleapMetaDataHelper.h +++ b/Sources/ObjCSources/GleapMetaDataHelper.h @@ -8,7 +8,7 @@ #import #import -#define SDK_VERSION @"14.0.2" +#define SDK_VERSION @"14.0.3" NS_ASSUME_NONNULL_BEGIN diff --git a/Sources/ObjCSources/GleapScreenCaptureHelper.m b/Sources/ObjCSources/GleapScreenCaptureHelper.m index 1dc126b..99329af 100644 --- a/Sources/ObjCSources/GleapScreenCaptureHelper.m +++ b/Sources/ObjCSources/GleapScreenCaptureHelper.m @@ -24,7 +24,17 @@ + (UIImage *)captureScreen { return nil; } - UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; + UIWindow *keyWindow = nil; + if (@available(iOS 13.0, *)) { + for (UIWindowScene *windowScene in [UIApplication sharedApplication].connectedScenes) { + if (windowScene.activationState == UISceneActivationStateForegroundActive) { + keyWindow = windowScene.windows.firstObject; + break; + } + } + } else { + keyWindow = [UIApplication sharedApplication].keyWindow; + } if (!keyWindow) { NSLog(@"Error: keyWindow is nil"); return nil; diff --git a/Sources/ObjCSources/GleapUIOverlayViewController.m b/Sources/ObjCSources/GleapUIOverlayViewController.m index 918a015..ee03662 100644 --- a/Sources/ObjCSources/GleapUIOverlayViewController.m +++ b/Sources/ObjCSources/GleapUIOverlayViewController.m @@ -314,6 +314,8 @@ - (void)renderNotifications { [_notificationsContainerView.widthAnchor constraintEqualToConstant: width].active = YES; [_notificationsContainerView.heightAnchor constraintEqualToConstant: containerHeight].active = YES; + int notificationViewOffsetY = [Gleap sharedInstance].notificationViewOffsetY; + NSString *feedbackButtonPosition = [config objectForKey: @"feedbackButtonPosition"]; if ([feedbackButtonPosition isEqualToString: @"BUTTON_CLASSIC_LEFT"]) { [_notificationsContainerView.bottomAnchor constraintEqualToAnchor: window.safeAreaLayoutGuide.bottomAnchor constant: -20].active = YES; @@ -329,7 +331,7 @@ - (void)renderNotifications { [_notificationsContainerView.bottomAnchor constraintEqualToAnchor: self.feedbackButton.topAnchor constant: -10].active = YES; [_notificationsContainerView.leadingAnchor constraintEqualToAnchor: self.feedbackButton.leadingAnchor constant: 0].active = YES; } else { - [_notificationsContainerView.bottomAnchor constraintEqualToAnchor: window.safeAreaLayoutGuide.bottomAnchor constant: -20].active = YES; + [_notificationsContainerView.bottomAnchor constraintEqualToAnchor: window.safeAreaLayoutGuide.bottomAnchor constant: -notificationViewOffsetY].active = YES; [_notificationsContainerView.leadingAnchor constraintEqualToAnchor: window.safeAreaLayoutGuide.leadingAnchor constant: 20].active = YES; } } else if ([feedbackButtonPosition isEqualToString: @"BOTTOM_RIGHT"]) { @@ -337,7 +339,7 @@ - (void)renderNotifications { [_notificationsContainerView.bottomAnchor constraintEqualToAnchor: self.feedbackButton.topAnchor constant: -10].active = YES; [_notificationsContainerView.trailingAnchor constraintEqualToAnchor: self.feedbackButton.trailingAnchor constant: 0].active = YES; } else { - [_notificationsContainerView.bottomAnchor constraintEqualToAnchor: window.safeAreaLayoutGuide.bottomAnchor constant: -20].active = YES; + [_notificationsContainerView.bottomAnchor constraintEqualToAnchor: window.safeAreaLayoutGuide.bottomAnchor constant: -notificationViewOffsetY].active = YES; [_notificationsContainerView.trailingAnchor constraintEqualToAnchor: window.safeAreaLayoutGuide.trailingAnchor constant: -20].active = YES; } } else if ([feedbackButtonPosition isEqualToString: @"BUTTON_NONE"]) { @@ -345,7 +347,8 @@ - (void)renderNotifications { [_notificationsContainerView.bottomAnchor constraintEqualToAnchor: self.feedbackButton.topAnchor constant: -10].active = YES; [_notificationsContainerView.trailingAnchor constraintEqualToAnchor: self.feedbackButton.trailingAnchor constant: 0].active = YES; } else { - [_notificationsContainerView.bottomAnchor constraintEqualToAnchor: window.safeAreaLayoutGuide.bottomAnchor constant: -20].active = YES; + + [_notificationsContainerView.bottomAnchor constraintEqualToAnchor: window.safeAreaLayoutGuide.bottomAnchor constant: -notificationViewOffsetY].active = YES; [_notificationsContainerView.trailingAnchor constraintEqualToAnchor: window.safeAreaLayoutGuide.trailingAnchor constant: -20].active = YES; } }