iOS: Move off deprecated APIs

- Request an orientation update with setNeedsUpdateOfSupportedInterfaceOrientations
  on iOS 16+, where attemptRotationToDeviceOrientation is deprecated.
- Open the document picker with UTTypes on iOS 14+, and present it from
  sharedViewController rather than through the deprecated keyWindow.
- List cameras with a discovery session instead of devicesWithMediaType.
- IS_IPAD() instead of UI_USER_INTERFACE_IDIOM().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-10 16:28:27 +02:00
1 parent 3375fbdbbd
commit 2e08b54402
5 files changed
+42 -23

No files matched your search

+2
View File
@@ -968,6 +968,8 @@ elseif(IOS AND NOT LIBRETRO)
if(EXISTS "${CMAKE_IOS_SDK_ROOT}/System/Library/Frameworks/PhotosUI.framework")
list(APPEND targetExtraLibs "-weak_framework PhotosUI")
endif()
# Weak, since it's iOS 14+ and we still run on 13.
list(APPEND targetExtraLibs "-weak_framework UniformTypeIdentifiers")
if(USE_IAP)
# Adding the In-App Purchase capability in Xcode did this. There's no entitlement for it on iOS.
list(APPEND targetExtraLibs "-framework StoreKit")
+19 -17
View File
@@ -32,6 +32,7 @@
#if __has_include(<UIKit/UIKit.h>)
#include "../ios/ViewControllerCommon.h"
#include <UIKit/UIKit.h>
#include <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
@interface DocumentPickerDelegate : NSObject <UIDocumentPickerDelegate>
@property DarwinDirectoryPanelCallback panelCallback;
@@ -279,27 +280,28 @@ void DarwinFileSystemServices::presentDirectoryPanel(
panelCallback(false, Path());
}
#elif PPSSPP_PLATFORM(IOS)
UIViewController *rootViewController = UIApplication.sharedApplication
.keyWindow
.rootViewController;
// get current window view controller
// The window's root view controller.
UIViewController *rootViewController = sharedViewController;
if (!rootViewController)
return;
NSMutableArray<NSString *> *types = [NSMutableArray array];
UIDocumentPickerMode pickerMode = UIDocumentPickerModeOpen;
if (allowDirectories)
[types addObject: (__bridge NSString *)kUTTypeFolder];
if (allowFiles) {
[types addObject: (__bridge NSString *)kUTTypeItem];
// NOTE: We do not want to copy files here - we handle it ourselves if needed.
// Previously this was Import mode.
pickerMode = UIDocumentPickerModeOpen;
// Open, not import - we don't want the files copied, we handle that ourselves if needed.
UIDocumentPickerViewController *pickerVC;
if (@available(iOS 14.0, *)) {
NSMutableArray<UTType *> *types = [NSMutableArray array];
if (allowDirectories)
[types addObject:UTTypeFolder];
if (allowFiles)
[types addObject:UTTypeItem];
pickerVC = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:types];
} else {
NSMutableArray<NSString *> *types = [NSMutableArray array];
if (allowDirectories)
[types addObject:(__bridge NSString *)kUTTypeFolder];
if (allowFiles)
[types addObject:(__bridge NSString *)kUTTypeItem];
pickerVC = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:types inMode:UIDocumentPickerModeOpen];
}
UIDocumentPickerViewController *pickerVC = [[UIDocumentPickerViewController alloc] initWithDocumentTypes: types inMode: pickerMode];
// What if you wanted to go to heaven, but then God showed you the next few lines?
// serious note: have to do this, because __pickerDelegate has to stay retained as a class property
__pickerDelegate = (void *)CFBridgingRetain([[DocumentPickerDelegate alloc] initWithCallback:panelCallback]);
+1 -1
View File
@@ -234,7 +234,7 @@ static std::vector<std::string> GatherGameLibrary() {
return UIInterfaceOrientationMaskLandscapeRight;
case ROTATION_LOCKED_VERTICAL:
case ROTATION_LOCKED_VERTICAL180:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
if (IS_IPAD()) {
// iPad supports both portrait orientations, so allow them.
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
+14 -2
View File
@@ -14,9 +14,21 @@
@implementation CameraHelper
static NSArray<AVCaptureDevice *> *GetVideoDevices() {
NSArray<AVCaptureDeviceType> *types = @[
AVCaptureDeviceTypeBuiltInWideAngleCamera,
AVCaptureDeviceTypeBuiltInUltraWideCamera,
AVCaptureDeviceTypeBuiltInTelephotoCamera,
AVCaptureDeviceTypeBuiltInTrueDepthCamera,
];
return [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:types
mediaType:AVMediaTypeVideo
position:AVCaptureDevicePositionUnspecified].devices;
}
std::vector<std::string> System_GetCameraDeviceList() {
std::vector<std::string> deviceList;
for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
for (AVCaptureDevice *device in GetVideoDevices()) {
deviceList.push_back([device.localizedName UTF8String]);
}
return deviceList;
@@ -76,7 +88,7 @@ NSString *getSelectedCamera() {
AVCaptureDeviceInput *videoInput = nil;
NSString *selectedCamera = getSelectedCamera();
for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
for (AVCaptureDevice *device in GetVideoDevices()) {
if ([device.localizedName isEqualToString:selectedCamera]) {
videoInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
}
+6 -3
View File
@@ -452,11 +452,14 @@ void System_Notify(SystemNotification notification) {
});
break;
case SystemNotification::ROTATE_UPDATED:
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_main_queue(), ^{
if (sharedViewController) {
// [sharedViewController setNeedsUpdateOfSupportedInterfaceOrientations];
INFO_LOG(Log::System, "Requesting device orientation update");
[UIViewController attemptRotationToDeviceOrientation];
if (@available(iOS 16.0, *)) {
[sharedViewController setNeedsUpdateOfSupportedInterfaceOrientations];
} else {
[UIViewController attemptRotationToDeviceOrientation];
}
}
});
break;