From 2ed93442e71b35c51d1ac1dd95e99cb9dc14c53a Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Thu, 1 Aug 2019 10:42:14 +0300 Subject: [PATCH] [iOS] Fixed location manager --- .../AlertController/MWMAlertViewController.h | 2 +- .../AlertController/MWMAlertViewController.mm | 4 +- .../Classes/CustomAlert/BaseAlert/MWMAlert.h | 2 +- .../Classes/CustomAlert/BaseAlert/MWMAlert.mm | 5 +- .../LocationAlert/MWMLocationAlert.h | 2 +- .../LocationAlert/MWMLocationAlert.mm | 6 +- .../SideButtons/MWMSideButtons.mm | 89 ++++--------------- iphone/Maps/Classes/MapViewController.mm | 5 +- .../Maps/Core/Location/MWMLocationManager.h | 3 + .../Maps/Core/Location/MWMLocationManager.mm | 62 ++++++++----- 10 files changed, 75 insertions(+), 105 deletions(-) diff --git a/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.h b/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.h index 87320bf5e1..d6fec4867f 100644 --- a/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.h +++ b/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.h @@ -14,7 +14,7 @@ needToRebuild:(BOOL)needToRebuild; - (void)presentRoutingDisclaimerAlertWithOkBlock:(nonnull nonnull MWMVoidBlock)block; - (void)presentDisabledLocationAlert; -- (void)presentLocationAlert; +- (void)presentLocationAlertWithCancelBlock:(MWMVoidBlock)cancelBlock; - (void)presentLocationServiceNotSupportedAlert; - (void)presentLocationNotFoundAlertWithOkBlock:(nonnull MWMVoidBlock)okBlock; - (void)presentNoConnectionAlert; diff --git a/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.mm b/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.mm index 0b886ccdba..b97f9c721e 100644 --- a/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.mm +++ b/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.mm @@ -51,10 +51,10 @@ static NSString * const kAlertControllerNibIdentifier = @"MWMAlertViewController #pragma mark - Actions - (void)presentRateAlert { [self displayAlert:[MWMAlert rateAlert]]; } -- (void)presentLocationAlert +- (void)presentLocationAlertWithCancelBlock:(MWMVoidBlock)cancelBlock { if (![MapViewController sharedController].welcomePageController) - [self displayAlert:[MWMAlert locationAlert]]; + [self displayAlert:[MWMAlert locationAlertWithCancelBlock: cancelBlock]]; } - (void)presentPoint2PointAlertWithOkBlock:(nonnull MWMVoidBlock)okBlock needToRebuild:(BOOL)needToRebuild diff --git a/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.h b/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.h index 04ea557185..813bcc2eee 100644 --- a/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.h +++ b/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.h @@ -5,7 +5,7 @@ + (MWMAlert *)routingMigrationAlertWithOkBlock:(MWMVoidBlock)okBlock; + (MWMAlert *)rateAlert; -+ (MWMAlert *)locationAlert; ++ (MWMAlert *)locationAlertWithCancelBlock:(MWMVoidBlock)cancelBlock; + (MWMAlert *)routingDisclaimerAlertWithOkBlock:(MWMVoidBlock)block; + (MWMAlert *)disabledLocationAlert; + (MWMAlert *)noWiFiAlertWithOkBlock:(MWMVoidBlock)okBlock andCancelBlock:(MWMVoidBlock)cancelBlock; diff --git a/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.mm b/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.mm index a0d15e7777..357256e700 100644 --- a/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.mm +++ b/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.mm @@ -15,7 +15,10 @@ @implementation MWMAlert + (MWMAlert *)rateAlert { return [MWMRateAlert alert]; } -+ (MWMAlert *)locationAlert { return [MWMLocationAlert alert]; } ++ (MWMAlert *)locationAlertWithCancelBlock:(MWMVoidBlock)cancelBlock { + return [MWMLocationAlert alertWithCancelBlock:cancelBlock]; +} + + (MWMAlert *)point2PointAlertWithOkBlock:(MWMVoidBlock)block needToRebuild:(BOOL)needToRebuild { return [MWMDefaultAlert point2PointAlertWithOkBlock:block needToRebuild:needToRebuild]; diff --git a/iphone/Maps/Classes/CustomAlert/LocationAlert/MWMLocationAlert.h b/iphone/Maps/Classes/CustomAlert/LocationAlert/MWMLocationAlert.h index 804eb1a86c..3c21d5ea35 100644 --- a/iphone/Maps/Classes/CustomAlert/LocationAlert/MWMLocationAlert.h +++ b/iphone/Maps/Classes/CustomAlert/LocationAlert/MWMLocationAlert.h @@ -2,6 +2,6 @@ @interface MWMLocationAlert : MWMAlert -+ (instancetype)alert; ++ (instancetype)alertWithCancelBlock:(MWMVoidBlock)cancelBlock; @end diff --git a/iphone/Maps/Classes/CustomAlert/LocationAlert/MWMLocationAlert.mm b/iphone/Maps/Classes/CustomAlert/LocationAlert/MWMLocationAlert.mm index 0e398e849b..2b014e69f5 100644 --- a/iphone/Maps/Classes/CustomAlert/LocationAlert/MWMLocationAlert.mm +++ b/iphone/Maps/Classes/CustomAlert/LocationAlert/MWMLocationAlert.mm @@ -9,17 +9,19 @@ static NSString * const kStatisticsEvent = @"Location Alert"; @interface MWMLocationAlert () @property (weak, nonatomic) IBOutlet UIButton * rightButton; +@property (nullable, nonatomic) MWMVoidBlock cancelBlock; @end @implementation MWMLocationAlert -+ (instancetype)alert ++ (instancetype)alertWithCancelBlock:(MWMVoidBlock)cancelBlock { [Statistics logEvent:kStatisticsEvent withParameters:@{kStatAction : kStatOpen}]; MWMLocationAlert * alert = [NSBundle.mainBundle loadNibNamed:kLocationAlertNibName owner:nil options:nil].firstObject; [alert setNeedsCloseAlertAfterEnterBackground]; + alert.cancelBlock = cancelBlock; return alert; } @@ -37,7 +39,7 @@ static NSString * const kStatisticsEvent = @"Location Alert"; - (IBAction)closeTap { [Statistics logEvent:kStatisticsEvent withParameters:@{kStatAction : kStatClose}]; - [self close:nil]; + [self close:self.cancelBlock]; } @end diff --git a/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm b/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm index b21ebc590b..db2acf7440 100644 --- a/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm +++ b/iphone/Maps/Classes/CustomViews/MapViewControls/SideButtons/MWMSideButtons.mm @@ -1,5 +1,6 @@ #import "MWMSideButtons.h" #import "MWMButton.h" +#import "MWMLocationManager.h" #import "MWMMapViewControlsManager.h" #import "MWMRouter.h" #import "MWMSettings.h" @@ -15,19 +16,6 @@ extern NSString * const kAlohalyticsTapEventKey; namespace { NSString * const kMWMSideButtonsViewNibName = @"MWMSideButtonsView"; - -NSArray * animationImages(NSString * animationTemplate, NSUInteger imagesCount) -{ - NSMutableArray * images = [NSMutableArray arrayWithCapacity:imagesCount]; - NSString * mode = [UIColor isNightMode] ? @"dark" : @"light"; - for (NSUInteger i = 1; i <= imagesCount; i += 1) - { - NSString * name = - [NSString stringWithFormat:@"%@_%@_%@", animationTemplate, mode, @(i).stringValue]; - [images addObject:static_cast([UIImage imageNamed:name])]; - } - return images.copy; -} } // namespace @interface MWMMapViewControlsManager () @@ -85,51 +73,11 @@ NSArray * animationImages(NSString * animationTemplate, NSUInteger im - (void)mwm_refreshUI { [self.sideView mwm_refreshUI]; - [self.locationButton.imageView stopRotation]; [self refreshLocationButtonState:self.locationMode]; } - (void)processMyPositionStateModeEvent:(MWMMyPositionMode)mode { - UIButton * locBtn = self.locationButton; - [locBtn.imageView stopRotation]; - - NSArray * images = - ^NSArray *(MWMMyPositionMode oldMode, MWMMyPositionMode newMode) - { - switch (newMode) - { - case MWMMyPositionModeNotFollow: - case MWMMyPositionModeNotFollowNoPosition: - if (oldMode == MWMMyPositionModeFollowAndRotate) - return animationImages(@"btn_follow_and_rotate_to_get_position", 3); - else if (oldMode == MWMMyPositionModeFollow) - return animationImages(@"btn_follow_to_get_position", 3); - return nil; - case MWMMyPositionModeFollow: - if (oldMode == MWMMyPositionModeFollowAndRotate) - return animationImages(@"btn_follow_and_rotate_to_follow", 3); - else if (oldMode == MWMMyPositionModeNotFollow || - oldMode == MWMMyPositionModeNotFollowNoPosition) - return animationImages(@"btn_get_position_to_follow", 3); - return nil; - case MWMMyPositionModePendingPosition: return nil; - case MWMMyPositionModeFollowAndRotate: - if (oldMode == MWMMyPositionModeFollow) - return animationImages(@"btn_follow_to_follow_and_rotate", 3); - return nil; - } - } - (self.locationMode, mode); - locBtn.imageView.animationImages = images; - if (images) - { - locBtn.imageView.animationDuration = 0.0; - locBtn.imageView.animationRepeatCount = 1; - locBtn.imageView.image = images.lastObject; - [locBtn.imageView startAnimating]; - } - [locBtn.imageView stopRotation]; [self refreshLocationButtonState:mode]; self.locationMode = mode; } @@ -138,29 +86,21 @@ NSArray * animationImages(NSString * animationTemplate, NSUInteger im - (void)refreshLocationButtonState:(MWMMyPositionMode)state { - dispatch_async(dispatch_get_main_queue(), ^{ - if (self.locationButton.imageView.isRotating) + MWMButton * locBtn = self.locationButton; + [locBtn.imageView stopRotation]; + switch (state) + { + case MWMMyPositionModePendingPosition: { - [self refreshLocationButtonState:state]; + locBtn.imageName = @"btn_pending"; + [locBtn.imageView startRotation:1]; + break; } - else - { - MWMButton * locBtn = self.locationButton; - switch (state) - { - case MWMMyPositionModePendingPosition: - { - locBtn.imageName = @"btn_pending"; - [locBtn.imageView startRotation:1]; - break; - } - case MWMMyPositionModeNotFollow: - case MWMMyPositionModeNotFollowNoPosition: locBtn.imageName = @"btn_get_position"; break; - case MWMMyPositionModeFollow: locBtn.imageName = @"btn_follow"; break; - case MWMMyPositionModeFollowAndRotate: locBtn.imageName = @"btn_follow_and_rotate"; break; - } - } - }); + case MWMMyPositionModeNotFollow: + case MWMMyPositionModeNotFollowNoPosition: locBtn.imageName = @"btn_get_position"; break; + case MWMMyPositionModeFollow: locBtn.imageName = @"btn_follow"; break; + case MWMMyPositionModeFollowAndRotate: locBtn.imageName = @"btn_follow_and_rotate"; break; + } } #pragma mark - Actions @@ -191,6 +131,7 @@ NSArray * animationImages(NSString * animationTemplate, NSUInteger im - (IBAction)locationTouchUpInside { [Statistics logEvent:kStatMenu withParameters:@{kStatButton : kStatLocation}]; + [MWMLocationManager enableLocationAlert]; GetFramework().SwitchMyPositionNextMode(); } diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index 6f83eb84cb..06f91043db 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -282,7 +282,8 @@ NSString * const kHotelFacilitiesSegue = @"Map2FacilitiesSegue"; self.view.clipsToBounds = YES; [MWMKeyboard addObserver:self]; self.welcomePageController = [MWMWelcomePageController controllerWithParent:self]; - [self processMyPositionStateModeEvent:MWMMyPositionModePendingPosition]; + [self processMyPositionStateModeEvent:[MWMLocationManager isLocationProhibited] ? + MWMMyPositionModeNotFollowNoPosition : MWMMyPositionModePendingPosition]; if ([MWMNavigationDashboardManager manager].state == MWMNavigationDashboardStateHidden) self.controlsManager.menuState = self.controlsManager.menuRestoreState; @@ -582,6 +583,8 @@ NSString * const kHotelFacilitiesSegue = @"Map2FacilitiesSegue"; case MWMMyPositionModePendingPosition: if (self.welcomePageController && [Alohalytics isFirstSession]) { break; } [MWMLocationManager start]; + if (![MWMLocationManager isStarted]) + [self processMyPositionStateModeEvent: MWMMyPositionModeNotFollowNoPosition]; break; case MWMMyPositionModeNotFollow: break; case MWMMyPositionModeFollow: diff --git a/iphone/Maps/Core/Location/MWMLocationManager.h b/iphone/Maps/Core/Location/MWMLocationManager.h index ede5ee84a5..8137463170 100644 --- a/iphone/Maps/Core/Location/MWMLocationManager.h +++ b/iphone/Maps/Core/Location/MWMLocationManager.h @@ -6,6 +6,7 @@ + (void)start; + (void)stop; ++ (BOOL)isStarted; + (void)addObserver:(id)observer; + (void)removeObserver:(id)observer; @@ -19,6 +20,8 @@ + (void)applicationDidBecomeActive; + (void)applicationWillResignActive; ++ (void)enableLocationAlert; + - (instancetype)init __attribute__((unavailable("call +manager instead"))); - (instancetype)copy __attribute__((unavailable("call +manager instead"))); - (instancetype)copyWithZone:(NSZone *)zone __attribute__((unavailable("call +manager instead"))); diff --git a/iphone/Maps/Core/Location/MWMLocationManager.mm b/iphone/Maps/Core/Location/MWMLocationManager.mm index 8697f4b092..a627d1c9a6 100644 --- a/iphone/Maps/Core/Location/MWMLocationManager.mm +++ b/iphone/Maps/Core/Location/MWMLocationManager.mm @@ -132,18 +132,29 @@ BOOL keepRunningInBackground() } NSString * const kLocationPermissionRequestedKey = @"kLocationPermissionRequestedKey"; +NSString * const kLocationAlertNeedShowKey = @"kLocationAlertNeedShowKey"; -BOOL isPermissionRequested() -{ +BOOL isPermissionRequested() { return [NSUserDefaults.standardUserDefaults boolForKey:kLocationPermissionRequestedKey]; } -void setPermissionRequested() -{ +void setPermissionRequested() { NSUserDefaults * ud = NSUserDefaults.standardUserDefaults; [ud setBool:YES forKey:kLocationPermissionRequestedKey]; [ud synchronize]; } + +BOOL needShowLocationAlert() { + if ([NSUserDefaults.standardUserDefaults objectForKey:kLocationAlertNeedShowKey] == nil) + return YES; + return [NSUserDefaults.standardUserDefaults boolForKey:kLocationAlertNeedShowKey]; +} + +void setShowLocationAlert(BOOL needShow) { + NSUserDefaults * ud = NSUserDefaults.standardUserDefaults; + [ud setBool:needShow forKey:kLocationAlertNeedShowKey]; + [ud synchronize]; +} } // namespace @interface MWMLocationManager () @@ -197,6 +208,8 @@ void setPermissionRequested() + (void)stop { [self manager].started = NO; } ++ (BOOL)isStarted { return [self manager].started; } + #pragma mark - Add/Remove Observers + (void)addObserver:(Observer)observer @@ -325,10 +338,12 @@ void setPermissionRequested() [[MWMAlertViewController activeAlertController] presentLocationServiceNotSupportedAlert]; break; case location::EDenied: - [[MWMAlertViewController activeAlertController] presentLocationAlert]; - break; case location::EGPSIsOff: - // iOS shows its own alert. + if (needShowLocationAlert()) { + [[MWMAlertViewController activeAlertController] presentLocationAlertWithCancelBlock:^{ + setShowLocationAlert(NO); + }]; + } break; } } @@ -472,20 +487,19 @@ void setPermissionRequested() if (_started == started) return; NSNotificationCenter * notificationCenter = NSNotificationCenter.defaultCenter; - if (started) - { + if (started) { _started = [self start]; - [notificationCenter addObserver:self - selector:@selector(orientationChanged) - name:UIDeviceOrientationDidChangeNotification - object:nil]; - [notificationCenter addObserver:self - selector:@selector(batteryStateChangedNotification:) - name:UIDeviceBatteryStateDidChangeNotification - object:nil]; - } - else - { + if (_started) { + [notificationCenter addObserver:self + selector:@selector(orientationChanged) + name:UIDeviceOrientationDidChangeNotification + object:nil]; + [notificationCenter addObserver:self + selector:@selector(batteryStateChangedNotification:) + name:UIDeviceBatteryStateDidChangeNotification + object:nil]; + } + } else { _started = NO; [self stop]; [notificationCenter removeObserver:self @@ -523,8 +537,6 @@ void setPermissionRequested() } else { - // Call start to make iOS show its alert to request geo service. - doStart(); [self processLocationStatus:location::EGPSIsOff]; } return NO; @@ -587,4 +599,10 @@ void setPermissionRequested() } } +#pragma mark - Location alert + ++ (void)enableLocationAlert { + setShowLocationAlert(YES); +} + @end