mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Support launching directly with the deep link, instead of just launching while already running.
This commit is contained in:
+5
-3
@@ -624,12 +624,14 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
|
||||
boot_filename = Path(str);
|
||||
skipLogo = true;
|
||||
}
|
||||
// This is needed on iOS, to fixup the path to match the current app directory, if it's stored in it.
|
||||
TryUpdateSavedPath(&boot_filename);
|
||||
if (okToLoad && okToCheck) {
|
||||
std::unique_ptr<FileLoader> fileLoader(ConstructFileLoader(boot_filename));
|
||||
if (!fileLoader->Exists()) {
|
||||
fprintf(stderr, "File not found: %s\n", boot_filename.c_str());
|
||||
#if defined(_WIN32) || defined(__ANDROID__)
|
||||
// Ignore and proceed.
|
||||
|
||||
#if defined(_WIN32) || defined(__ANDROID__) || PPSSPP_PLATFORM(IOS)
|
||||
boot_filename.clear();
|
||||
#else
|
||||
// Bail.
|
||||
@@ -639,7 +641,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Syntax error: Can only boot one file.\nNote: Many command line args need a =, like --appendconfig=FILENAME.ini.\n");
|
||||
#if defined(_WIN32) || defined(__ANDROID__)
|
||||
#if defined(_WIN32) || defined(__ANDROID__) || PPSSPP_PLATFORM(IOS)
|
||||
// Ignore and proceed.
|
||||
#else
|
||||
// Bail.
|
||||
|
||||
@@ -121,32 +121,6 @@ __attribute__((used)) static Class _forceLinkSceneDelegate = [SceneDelegate clas
|
||||
System_PostUIMessage(UIMessage::REQUEST_GAME_BOOT, gamePath.ToString());
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)app
|
||||
openURL:(NSURL *)url
|
||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
|
||||
// 1. Check the scheme
|
||||
if (![[url scheme] isEqualToString:@"ppsspp"]) {
|
||||
NSLog(@"PPSSPPUIApplication.openURL called with invalid URL: %@", url);
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSLog(@"PPSSPPUIApplication.openURL called with valid URL: %@", url);
|
||||
// 2. Parse the URL (using NSURLComponents is safer than manual string parsing)
|
||||
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
|
||||
NSArray *queryItems = [components queryItems];
|
||||
NSLog(@"PPSSPPUIApplication.openURL query items: %@", queryItems);
|
||||
for (NSURLQueryItem *item in queryItems) {
|
||||
if ([item.name isEqualToString:@"path"]) {
|
||||
NSString *receivedPath = item.value;
|
||||
[self processFilePath:receivedPath];
|
||||
} else {
|
||||
NSLog(@"PPSSPPUIApplication.openURL: Unrecognized query item: %@=%@", item.name, item.value);
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
|
||||
switch (g_Config.iScreenRotation) {
|
||||
case ROTATION_LOCKED_HORIZONTAL:
|
||||
|
||||
+67
-18
@@ -13,8 +13,31 @@
|
||||
#import "Core/Config.h"
|
||||
#import "Common/Log.h"
|
||||
#import "IAPManager.h"
|
||||
#include "Core/Util/PathUtil.h"
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#include <string>
|
||||
|
||||
static std::string gStartupArgStorage;
|
||||
|
||||
static NSString *ExtractDeepLinkPath(NSURL *url) {
|
||||
if (![[url scheme] isEqualToString:@"ppsspp"]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
|
||||
for (NSURLQueryItem *item in components.queryItems) {
|
||||
if ([item.name isEqualToString:@"path"] && item.value.length > 0) {
|
||||
return item.value;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@interface SceneDelegate ()
|
||||
@property (nonatomic, strong) NSString *pendingLaunchPath;
|
||||
@end
|
||||
|
||||
@implementation SceneDelegate
|
||||
|
||||
@@ -22,11 +45,37 @@
|
||||
NSLog(@"✅ SceneDelegate class was loaded!");
|
||||
}
|
||||
|
||||
- (void)capturePendingPathFromURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
|
||||
for (UIOpenURLContext *context in URLContexts) {
|
||||
NSString *path = ExtractDeepLinkPath(context.URL);
|
||||
if (path.length > 0) {
|
||||
self.pendingLaunchPath = path;
|
||||
NSLog(@"SceneDelegate: captured cold-start deep link path: %@", self.pendingLaunchPath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleURLContextsWhileRunning:(NSSet<UIOpenURLContext *> *)URLContexts {
|
||||
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
|
||||
for (UIOpenURLContext *context in URLContexts) {
|
||||
NSLog(@"SceneDelegate: openURLContexts called with URL: %@", context.URL);
|
||||
NSString *path = ExtractDeepLinkPath(context.URL);
|
||||
if (path.length > 0) {
|
||||
[appDelegate processFilePath:path];
|
||||
} else {
|
||||
NSLog(@"SceneDelegate: ignoring deep link URL (invalid scheme or missing path): %@", context.URL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
|
||||
if (![scene isKindOfClass:[UIWindowScene class]]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self capturePendingPathFromURLContexts:connectionOptions.URLContexts];
|
||||
|
||||
UIWindowScene *windowScene = (UIWindowScene *)scene;
|
||||
if (self.window) {
|
||||
NSLog(@"✅ Window already exists, not creating again!");
|
||||
@@ -43,12 +92,26 @@
|
||||
|
||||
int argc = 1;
|
||||
char *argv[5]{};
|
||||
NSString *startupPath = nil;
|
||||
NSURL *nsUrl = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
|
||||
|
||||
if (nsUrl != nullptr && nsUrl.isFileURL) {
|
||||
if (self.pendingLaunchPath.length > 0) {
|
||||
startupPath = self.pendingLaunchPath;
|
||||
self.pendingLaunchPath = nil;
|
||||
}
|
||||
|
||||
if (startupPath == nil && nsUrl != nullptr && nsUrl.isFileURL) {
|
||||
NSString *nsString = nsUrl.path;
|
||||
const char *string = nsString.UTF8String;
|
||||
argv[argc++] = (char*)string;
|
||||
startupPath = nsString;
|
||||
}
|
||||
|
||||
if (startupPath.length > 0) {
|
||||
// Keep cold-start argv behavior aligned with processFilePath().
|
||||
std::string startupPathUtf8(startupPath.UTF8String);
|
||||
Path gamePath(startupPathUtf8);
|
||||
gStartupArgStorage = gamePath.ToString();
|
||||
argv[argc++] = (char *)gStartupArgStorage.c_str();
|
||||
NSLog(@"SceneDelegate: startup path passed to argv: %s", gStartupArgStorage.c_str());
|
||||
}
|
||||
|
||||
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
|
||||
@@ -96,21 +159,7 @@
|
||||
}
|
||||
|
||||
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
|
||||
for (UIOpenURLContext *context in URLContexts) {
|
||||
NSLog(@"SceneDelegate: openURLContexts called with URL: %@", context.URL);
|
||||
NSURL *url = context.URL;
|
||||
if (![[url scheme] isEqualToString:@"ppsspp"]) {
|
||||
NSLog(@"SceneDelegate: ignoring URL with unknown scheme: %@", url);
|
||||
continue;
|
||||
}
|
||||
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
|
||||
for (NSURLQueryItem *item in components.queryItems) {
|
||||
if ([item.name isEqualToString:@"path"]) {
|
||||
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
|
||||
[appDelegate processFilePath:item.value];
|
||||
}
|
||||
}
|
||||
}
|
||||
[self handleURLContextsWhileRunning:URLContexts];
|
||||
}
|
||||
|
||||
- (void)sceneWillResignActive:(UIScene *)scene {
|
||||
|
||||
@@ -699,6 +699,10 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
PROFILE_INIT();
|
||||
|
||||
#if PPSSPP_PLATFORM(IOS_APP_STORE) && defined(_DEBUG)
|
||||
g_logManager.SetOutputsEnabled(LogOutput::Stdio);
|
||||
#endif
|
||||
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, NSStringFromClass([PPSSPPUIApplication class]), NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user