From 78b54acad41e2697db910ed9b6e66625004526c0 Mon Sep 17 00:00:00 2001 From: Yannik Bloscheck Date: Tue, 24 Jun 2025 16:14:33 +0200 Subject: [PATCH] [ios] Switching to iOS 15 as the minimum Signed-off-by: Yannik Bloscheck --- iphone/CoreApi/CoreApi/Common/AppInfo.mm | 2 +- iphone/CoreApi/CoreApi/Common/MWMCommon.h | 6 ---- .../UIApplication+LoadingOverlay.swift | 2 +- .../Maps/Classes/CarPlay/CarPlayService.swift | 2 +- .../ListTemplateBuilder.swift | 8 ++--- .../MapTemplateBuilder.swift | 32 +++++-------------- .../Classes/Components/CopyableLabel.swift | 2 +- .../AlertController/MWMAlertViewController.mm | 12 +++++++ .../Classes/CustomAlert/BaseAlert/MWMAlert.mm | 13 -------- .../Classes/CustomAlert/Toast/Toast.swift | 2 +- iphone/Maps/Classes/EAGLView.mm | 2 +- iphone/Maps/Classes/MapViewController.mm | 17 ++++------ iphone/Maps/Classes/MapsAppDelegate.mm | 6 ---- iphone/Maps/CoMaps.plist | 2 ++ iphone/Maps/Common/Common.swift | 5 --- iphone/Maps/Common/MWMMacros.h | 2 +- .../Maps/Core/Location/MWMLocationManager.mm | 8 ++--- .../Core/Search/MWMSearch+CoreSpotlight.mm | 2 +- .../Maps/Core/Theme/Core/StyleManager.swift | 8 +++-- .../Theme/Extensions/UIFont+monospaced.swift | 4 +-- platform/platform_ios.mm | 2 +- xcode/common.xcconfig | 2 +- 22 files changed, 52 insertions(+), 89 deletions(-) diff --git a/iphone/CoreApi/CoreApi/Common/AppInfo.mm b/iphone/CoreApi/CoreApi/Common/AppInfo.mm index 444cdfa40..d97813a30 100644 --- a/iphone/CoreApi/CoreApi/Common/AppInfo.mm +++ b/iphone/CoreApi/CoreApi/Common/AppInfo.mm @@ -89,7 +89,7 @@ - (BOOL)canMakeCalls { - if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone) + if (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPhone) return NO; NSURL * telURL = [NSURL URLWithString:@"tel://"]; if (![UIApplication.sharedApplication canOpenURL:telURL]) diff --git a/iphone/CoreApi/CoreApi/Common/MWMCommon.h b/iphone/CoreApi/CoreApi/Common/MWMCommon.h index 85ec85bda..ed9c3d975 100644 --- a/iphone/CoreApi/CoreApi/Common/MWMCommon.h +++ b/iphone/CoreApi/CoreApi/Common/MWMCommon.h @@ -50,12 +50,6 @@ static inline BOOL equalScreenDimensions(CGFloat left, CGFloat right) return fabs(left - right) < 0.5; } -static inline CGFloat statusBarHeight(void) NS_EXTENSION_UNAVAILABLE_IOS("Not available in extensions") -{ - CGSize const statusBarSize = UIApplication.sharedApplication.statusBarFrame.size; - return MIN(statusBarSize.height, statusBarSize.width); -} - static inline void performOnce(MWMVoidBlock block, NSString *key) { BOOL performed = [[NSUserDefaults standardUserDefaults] boolForKey:key]; if (!performed) { diff --git a/iphone/Maps/Categories/UIApplication+LoadingOverlay.swift b/iphone/Maps/Categories/UIApplication+LoadingOverlay.swift index c51b98550..9e5fe2d4f 100644 --- a/iphone/Maps/Categories/UIApplication+LoadingOverlay.swift +++ b/iphone/Maps/Categories/UIApplication+LoadingOverlay.swift @@ -3,7 +3,7 @@ extension UIApplication { @objc func showLoadingOverlay(completion: (() -> Void)? = nil) { - guard let window = self.windows.first(where: { $0.isKeyWindow }) else { + guard let window = (self.connectedScenes.filter { $0.activationState == .foregroundActive }.first(where: { $0 is UIWindowScene }) as? UIWindowScene)?.windows.first(where: { $0.isKeyWindow }) else { completion?() return } diff --git a/iphone/Maps/Classes/CarPlay/CarPlayService.swift b/iphone/Maps/Classes/CarPlay/CarPlayService.swift index 9a22a7461..20c33532d 100644 --- a/iphone/Maps/Classes/CarPlay/CarPlayService.swift +++ b/iphone/Maps/Classes/CarPlay/CarPlayService.swift @@ -270,7 +270,7 @@ final class CarPlayService: NSObject { let alert = CPNavigationAlert(titleVariants: [L("trip_finished")], subtitleVariants: [subtitle], - imageSet: nil, + image: nil, primaryAction: doneAction, secondaryAction: nil, duration: 0) diff --git a/iphone/Maps/Classes/CarPlay/Template Builders/ListTemplateBuilder.swift b/iphone/Maps/Classes/CarPlay/Template Builders/ListTemplateBuilder.swift index 910d3de8d..d0121aee1 100644 --- a/iphone/Maps/Classes/CarPlay/Template Builders/ListTemplateBuilder.swift +++ b/iphone/Maps/Classes/CarPlay/Template Builders/ListTemplateBuilder.swift @@ -125,13 +125,9 @@ final class ListTemplateBuilder { private class func buildBarButton(type: BarButtonType, action: ((CPBarButton) -> Void)?) -> CPBarButton { switch type { case .bookmarks: - let button = CPBarButton(type: .image, handler: action) - button.image = UIImage(named: "ic_carplay_bookmark") - return button + return CPBarButton(image: UIImage(named: "ic_carplay_bookmark")!, handler: action) case .search: - let button = CPBarButton(type: .image, handler: action) - button.image = UIImage(named: "ic_carplay_keyboard") - return button + return CPBarButton(image: UIImage(named: "ic_carplay_keyboard")!, handler: action) } } } diff --git a/iphone/Maps/Classes/CarPlay/Template Builders/MapTemplateBuilder.swift b/iphone/Maps/Classes/CarPlay/Template Builders/MapTemplateBuilder.swift index 594fc7fbb..2267a3548 100644 --- a/iphone/Maps/Classes/CarPlay/Template Builders/MapTemplateBuilder.swift +++ b/iphone/Maps/Classes/CarPlay/Template Builders/MapTemplateBuilder.swift @@ -166,37 +166,21 @@ final class MapTemplateBuilder { private class func buildBarButton(type: BarButtonType, action: ((CPBarButton) -> Void)?) -> CPBarButton { switch type { case .dismissPaning: - let button = CPBarButton(type: .text, handler: action) - button.title = L("done") - return button + return CPBarButton(title: L("done"), handler: action) case .destination: - let button = CPBarButton(type: .text, handler: action) - button.title = L("pick_destination") - return button + return CPBarButton(title: L("pick_destination"), handler: action) case .recenter: - let button = CPBarButton(type: .text, handler: action) - button.title = L("follow_my_position") - return button + return CPBarButton(title: L("follow_my_position"), handler: action) case .settings: - let button = CPBarButton(type: .image, handler: action) - button.image = UIImage(named: "ic_carplay_settings") - return button + return CPBarButton(image: UIImage(named: "ic_carplay_settings")!, handler: action) case .mute: - let button = CPBarButton(type: .image, handler: action) - button.image = UIImage(named: "ic_carplay_unmuted") - return button + return CPBarButton(image: UIImage(named: "ic_carplay_unmuted")!, handler: action) case .unmute: - let button = CPBarButton(type: .image, handler: action) - button.image = UIImage(named: "ic_carplay_muted") - return button + return CPBarButton(image: UIImage(named: "ic_carplay_muted")!, handler: action) case .redirectRoute: - let button = CPBarButton(type: .image, handler: action) - button.image = UIImage(named: "ic_carplay_redirect_route") - return button + return CPBarButton(image: UIImage(named: "ic_carplay_redirect_route")!, handler: action) case .endRoute: - let button = CPBarButton(type: .text, handler: action) - button.title = L("navigation_stop_button").capitalized - return button + return CPBarButton(title: L("navigation_stop_button").capitalized, handler: action) } } } diff --git a/iphone/Maps/Classes/Components/CopyableLabel.swift b/iphone/Maps/Classes/Components/CopyableLabel.swift index 18d311f75..3f90df4c1 100644 --- a/iphone/Maps/Classes/Components/CopyableLabel.swift +++ b/iphone/Maps/Classes/Components/CopyableLabel.swift @@ -40,7 +40,7 @@ class CopyableLabel: UILabel { override func copy(_ sender: Any?) { UIPasteboard.general.string = text - UIMenuController.shared.setMenuVisible(false, animated: true) + UIMenuController.shared.hideMenu() } override var canBecomeFirstResponder: Bool { diff --git a/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.mm b/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.mm index 61b80d0fe..f2ef49818 100644 --- a/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.mm +++ b/iphone/Maps/Classes/CustomAlert/AlertController/MWMAlertViewController.mm @@ -210,6 +210,9 @@ static NSString *const kAlertControllerNibIdentifier = @"MWMAlertViewController" - (void)displayAlert:(MWMAlert *)alert { UIViewController *ownerVC = self.ownerViewController; + if (ownerVC.navigationController != nil) { + ownerVC = self.ownerViewController.navigationController; + } BOOL isOwnerLoaded = ownerVC.isViewLoaded; if (!isOwnerLoaded) { return; @@ -234,10 +237,19 @@ static NSString *const kAlertControllerNibIdentifier = @"MWMAlertViewController" } completion:nil]; + [self willMoveToParentViewController:NULL]; + [self.view removeFromSuperview]; [self removeFromParentViewController]; + alert.alertController = self; + [ownerVC addChildViewController:self]; + self.view.frame = CGRectMake(0, 0, ownerVC.view.frame.size.width, ownerVC.view.frame.size.height); + [ownerVC.view addSubview:self.view]; + [self didMoveToParentViewController:ownerVC]; + alert.alpha = 0.; + [self.view addSubview:alert]; CGFloat const scale = 1.1; alert.transform = CGAffineTransformMakeScale(scale, scale); [UIView animateWithDuration:kDefaultAnimationDuration diff --git a/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.mm b/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.mm index 4bda99e9e..e904cd793 100644 --- a/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.mm +++ b/iphone/Maps/Classes/CustomAlert/BaseAlert/MWMAlert.mm @@ -222,19 +222,6 @@ view.frame = window.bounds; } -- (void)setAlertController:(MWMAlertViewController *)alertController { - _alertController = alertController; - UIView *view = alertController.view; - UIViewController *ownerViewController = alertController.ownerViewController; - view.frame = ownerViewController.view.bounds; - [ownerViewController.view addSubview:view]; - [self addControllerViewToWindow]; - auto const orientation = UIApplication.sharedApplication.statusBarOrientation; - [self rotate:orientation duration:0.0]; - [view addSubview:self]; - self.frame = view.bounds; -} - - (void)layoutSubviews { [super layoutSubviews]; self.frame = self.superview.bounds; diff --git a/iphone/Maps/Classes/CustomAlert/Toast/Toast.swift b/iphone/Maps/Classes/CustomAlert/Toast/Toast.swift index e403105e2..aeccf36be 100644 --- a/iphone/Maps/Classes/CustomAlert/Toast/Toast.swift +++ b/iphone/Maps/Classes/CustomAlert/Toast/Toast.swift @@ -70,7 +70,7 @@ final class Toast: NSObject { private func show(withAlignment alignment: Alignment, pinToSafeArea: Bool) { Self.hideAll() - guard let view = UIApplication.shared.keyWindow else { return } + guard let view = (UIApplication.shared.connectedScenes.filter { $0.activationState == .foregroundActive }.first(where: { $0 is UIWindowScene }) as? UIWindowScene)?.keyWindow else { return } view.addSubview(blurView) let leadingConstraint = blurView.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: Constants.horizontalOffset) diff --git a/iphone/Maps/Classes/EAGLView.mm b/iphone/Maps/Classes/EAGLView.mm index 1a730321c..7a0ae3730 100644 --- a/iphone/Maps/Classes/EAGLView.mm +++ b/iphone/Maps/Classes/EAGLView.mm @@ -48,7 +48,7 @@ double getExactDPI(double contentScaleFactor) float const iPhoneDPI = 163.f; float const mDPI = 160.f; - switch (UI_USER_INTERFACE_IDIOM()) + switch (UIDevice.currentDevice.userInterfaceIdiom) { case UIUserInterfaceIdiomPhone: return iPhoneDPI * contentScaleFactor; diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index 4ad1ec01d..10c5e04b6 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -834,19 +834,14 @@ NSString *const kSettingsSegue = @"Map2Settings"; - (NSArray *)keyCommands { NSArray *commands = @[ - [UIKeyCommand keyCommandWithInput:UIKeyInputDownArrow modifierFlags:0 action:@selector(zoomOut)], // Alternative, not shown when holding CMD - [UIKeyCommand keyCommandWithInput:@"-" modifierFlags:UIKeyModifierCommand action:@selector(zoomOut) discoverabilityTitle:@"Zoom Out"], - [UIKeyCommand keyCommandWithInput:UIKeyInputUpArrow modifierFlags:0 action:@selector(zoomIn)], // Alternative, not shown when holding CMD - [UIKeyCommand keyCommandWithInput:@"=" modifierFlags:UIKeyModifierCommand action:@selector(zoomIn)], // Alternative, not shown when holding CMD - [UIKeyCommand keyCommandWithInput:@"+" modifierFlags:UIKeyModifierCommand action:@selector(zoomIn) discoverabilityTitle:@"Zoom In"], - [UIKeyCommand keyCommandWithInput:UIKeyInputEscape modifierFlags:0 action:@selector(goBack) discoverabilityTitle:@"Go Back"], - [UIKeyCommand keyCommandWithInput:@"0" modifierFlags:UIKeyModifierCommand action:@selector(switchPositionMode) discoverabilityTitle:@"Switch position mode"] + [UIKeyCommand commandWithTitle:@"Zoom Out" image:[UIImage systemImageNamed: @"minus.magnifyingglass"] action:@selector(zoomIn) input:@"-" modifierFlags:UIKeyModifierCommand propertyList:nil], + [UIKeyCommand commandWithTitle:@"Zoom In" image:[UIImage systemImageNamed: @"plus.magnifyingglass"] action:@selector(zoomIn) input:@"+" modifierFlags:UIKeyModifierCommand propertyList:nil], + [UIKeyCommand commandWithTitle:@"Go Back" image:nil action:@selector(goBack) input:UIKeyInputEscape modifierFlags:0 propertyList:nil], + [UIKeyCommand commandWithTitle:@"Switch position mode" image:nil action:@selector(switchPositionMode) input:@"0" modifierFlags:UIKeyModifierCommand propertyList:nil] ]; - if (@available(iOS 15, *)) { - for (UIKeyCommand *command in commands) { - command.wantsPriorityOverSystemBehavior = YES; - } + for (UIKeyCommand *command in commands) { + command.wantsPriorityOverSystemBehavior = YES; } return commands; diff --git a/iphone/Maps/Classes/MapsAppDelegate.mm b/iphone/Maps/Classes/MapsAppDelegate.mm index b77459f75..876f13b5e 100644 --- a/iphone/Maps/Classes/MapsAppDelegate.mm +++ b/iphone/Maps/Classes/MapsAppDelegate.mm @@ -259,9 +259,6 @@ using namespace osm_auth_ios; - (void)disableDownloadIndicator { --m_activeDownloadsCounter; if (m_activeDownloadsCounter <= 0) { - dispatch_async(dispatch_get_main_queue(), ^{ - UIApplication.sharedApplication.networkActivityIndicatorVisible = NO; - }); m_activeDownloadsCounter = 0; if (UIApplication.sharedApplication.applicationState == UIApplicationStateBackground) { [UIApplication.sharedApplication endBackgroundTask:m_backgroundTask]; @@ -272,9 +269,6 @@ using namespace osm_auth_ios; - (void)enableDownloadIndicator { ++m_activeDownloadsCounter; - dispatch_async(dispatch_get_main_queue(), ^{ - UIApplication.sharedApplication.networkActivityIndicatorVisible = YES; - }); } + (void)customizeAppearanceForNavigationBar:(UINavigationBar *)navigationBar { diff --git a/iphone/Maps/CoMaps.plist b/iphone/Maps/CoMaps.plist index b299ff8ea..0f8d361ad 100644 --- a/iphone/Maps/CoMaps.plist +++ b/iphone/Maps/CoMaps.plist @@ -161,6 +161,8 @@ app.comaps.3daction.route + UIApplicationSupportsMultipleScenes + UIBackgroundModes audio diff --git a/iphone/Maps/Common/Common.swift b/iphone/Maps/Common/Common.swift index 79f85d43f..2d1efa3e4 100644 --- a/iphone/Maps/Common/Common.swift +++ b/iphone/Maps/Common/Common.swift @@ -27,11 +27,6 @@ func toString(_ cls: AnyClass) -> String { return String(describing: cls) } -func statusBarHeight() -> CGFloat { - let statusBarSize = UIApplication.shared.statusBarFrame.size - return min(statusBarSize.height, statusBarSize.width) -} - func LOG(_ level: LogLevel, _ message: @autoclosure () -> Any, functionName: StaticString = #function, diff --git a/iphone/Maps/Common/MWMMacros.h b/iphone/Maps/Common/MWMMacros.h index 9b7010fcd..f24e089d7 100644 --- a/iphone/Maps/Common/MWMMacros.h +++ b/iphone/Maps/Common/MWMMacros.h @@ -1,3 +1,3 @@ -#define IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) +#define IPAD (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) #define L(str) NSLocalizedString(str, nil) diff --git a/iphone/Maps/Core/Location/MWMLocationManager.mm b/iphone/Maps/Core/Location/MWMLocationManager.mm index 22a9f5c25..01600a799 100644 --- a/iphone/Maps/Core/Location/MWMLocationManager.mm +++ b/iphone/Maps/Core/Location/MWMLocationManager.mm @@ -509,10 +509,10 @@ void setShowLocationAlert(BOOL needShow) { // Delegate's method didChangeAuthorizationStatus is used to handle the authorization status when the application finishes launching // or user changes location access in the application settings. -- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status +- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager { - LOG(LWARNING, ("CLLocationManagerDelegate: Authorization status has changed to", DebugPrint(status))); - switch (status) { + LOG(LWARNING, ("CLLocationManagerDelegate: Authorization status has changed to", DebugPrint(manager.authorizationStatus))); + switch (manager.authorizationStatus) { case kCLAuthorizationStatusAuthorizedWhenInUse: case kCLAuthorizationStatusAuthorizedAlways: [self startUpdatingLocationFor:manager]; @@ -579,7 +579,7 @@ void setShowLocationAlert(BOOL needShow) { if ([CLLocationManager locationServicesEnabled]) { CLLocationManager * locationManager = self.locationManager; - switch (CLLocationManager.authorizationStatus) + switch (locationManager.authorizationStatus) { case kCLAuthorizationStatusAuthorizedWhenInUse: case kCLAuthorizationStatusAuthorizedAlways: diff --git a/iphone/Maps/Core/Search/MWMSearch+CoreSpotlight.mm b/iphone/Maps/Core/Search/MWMSearch+CoreSpotlight.mm index ea7a0cfb8..32fc94f7a 100644 --- a/iphone/Maps/Core/Search/MWMSearch+CoreSpotlight.mm +++ b/iphone/Maps/Core/Search/MWMSearch+CoreSpotlight.mm @@ -24,7 +24,7 @@ for (auto const & categoryKey : categoriesKeys) { CSSearchableItemAttributeSet * attrSet = [[CSSearchableItemAttributeSet alloc] - initWithItemContentType:static_cast(kUTTypeItem)]; + initWithItemContentType: UTTypeItem.identifier]; NSString * categoryName = nil; NSMutableDictionary * localizedStrings = [@{} mutableCopy]; diff --git a/iphone/Maps/Core/Theme/Core/StyleManager.swift b/iphone/Maps/Core/Theme/Core/StyleManager.swift index 206b393d5..3ab8a2485 100644 --- a/iphone/Maps/Core/Theme/Core/StyleManager.swift +++ b/iphone/Maps/Core/Theme/Core/StyleManager.swift @@ -22,8 +22,12 @@ } func update () { - for window in UIApplication.shared.windows { - updateView(window.rootViewController?.view) + for scene in UIApplication.shared.connectedScenes { + if let windowsScene = scene as? UIWindowScene { + for window in windowsScene.windows { + updateView(window.rootViewController?.view) + } + } } let appDelegate = UIApplication.shared.delegate as! MapsAppDelegate diff --git a/iphone/Maps/Core/Theme/Extensions/UIFont+monospaced.swift b/iphone/Maps/Core/Theme/Extensions/UIFont+monospaced.swift index 89990edbc..35fa24329 100644 --- a/iphone/Maps/Core/Theme/Extensions/UIFont+monospaced.swift +++ b/iphone/Maps/Core/Theme/Extensions/UIFont+monospaced.swift @@ -7,8 +7,8 @@ extension UIFont { let attributes: [UIFontDescriptor.AttributeName: Any] = [ .featureSettings: [ [ - UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType, - UIFontDescriptor.FeatureKey.typeIdentifier: kMonospacedNumbersSelector + UIFontDescriptor.FeatureKey.type: kNumberSpacingType, + UIFontDescriptor.FeatureKey.selector: kMonospacedNumbersSelector ] ] ] diff --git a/platform/platform_ios.mm b/platform/platform_ios.mm index 5293673cd..191f1f373 100644 --- a/platform/platform_ios.mm +++ b/platform/platform_ios.mm @@ -36,7 +36,7 @@ Platform::Platform() { - m_isTablet = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad); + m_isTablet = (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad); NSBundle * bundle = NSBundle.mainBundle; NSString * path = [bundle resourcePath]; diff --git a/xcode/common.xcconfig b/xcode/common.xcconfig index f106f31da..20852c985 100644 --- a/xcode/common.xcconfig +++ b/xcode/common.xcconfig @@ -9,7 +9,7 @@ HEADER_SEARCH_PATHS = $(inherited) $(OMIM_ROOT) $(BOOST_ROOT) $(OMIM_ROOT)/3part FRAMEWORK_SEARCH_PATHS[sdk=macosx*] = $(QT_PATH)/lib // Deployment target -IPHONEOS_DEPLOYMENT_TARGET = 12.0 +IPHONEOS_DEPLOYMENT_TARGET = 15.6 // The minimum version that properly supports Qt6's std::filesystem for C++17 MACOSX_DEPLOYMENT_TARGET = 10.15