-
Notifications
You must be signed in to change notification settings - Fork 62
Allow file loading (including ROMs and pkgs) from Files app and share sheet #202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -66,6 +66,14 @@ - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(N | |||||||||||||||||||||||||||||||||||||||||
| [window makeKeyAndVisible]; | ||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Check if app was launched by opening a file | ||||||||||||||||||||||||||||||||||||||||||
| NSURL *url = launchOptions[UIApplicationLaunchOptionsURLKey]; | ||||||||||||||||||||||||||||||||||||||||||
| if (url) { | ||||||||||||||||||||||||||||||||||||||||||
| fprintf(stderr, "App launched with URL: %s\n", [[url absoluteString] UTF8String]); | ||||||||||||||||||||||||||||||||||||||||||
| // Handle the file immediately before emulator initialization | ||||||||||||||||||||||||||||||||||||||||||
| [self handleIncomingFile:url]; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| NSUserDefaults* prefs = [NSUserDefaults standardUserDefaults]; | ||||||||||||||||||||||||||||||||||||||||||
| bool clearFlash = [(NSNumber*) [prefs objectForKey:@"clear_flash_ram"] boolValue]; | ||||||||||||||||||||||||||||||||||||||||||
| if (clearFlash) | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -88,13 +96,88 @@ - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(N | |||||||||||||||||||||||||||||||||||||||||
| return YES; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - (void)handleIncomingFile:(NSURL *)url | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| if (![url.scheme isEqualToString:@"file"]) { | ||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| [url startAccessingSecurityScopedResource]; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); | ||||||||||||||||||||||||||||||||||||||||||
| NSString *documentsDirectory = [paths objectAtIndex:0]; | ||||||||||||||||||||||||||||||||||||||||||
| NSString *srcPath = url.path; | ||||||||||||||||||||||||||||||||||||||||||
| NSString *filename = [srcPath lastPathComponent]; | ||||||||||||||||||||||||||||||||||||||||||
| NSString *dstPath = [documentsDirectory stringByAppendingPathComponent:filename]; | ||||||||||||||||||||||||||||||||||||||||||
| NSError *error = nil; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Determine file type | ||||||||||||||||||||||||||||||||||||||||||
| NSString *fileExtension = [[filename pathExtension] lowercaseString]; | ||||||||||||||||||||||||||||||||||||||||||
| BOOL isROMFile = [fileExtension isEqualToString:@"rom"]; | ||||||||||||||||||||||||||||||||||||||||||
| BOOL isPkgFile = [fileExtension isEqualToString:@"pkg"] || [fileExtension isEqualToString:@"newtonpkg"]; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if(![srcPath isEqualToString:dstPath]) { | ||||||||||||||||||||||||||||||||||||||||||
| if ([[NSFileManager defaultManager] fileExistsAtPath:dstPath]) { | ||||||||||||||||||||||||||||||||||||||||||
| [[NSFileManager defaultManager] removeItemAtPath:dstPath error:&error]; | ||||||||||||||||||||||||||||||||||||||||||
| if(error){ | ||||||||||||||||||||||||||||||||||||||||||
| NSLog(@"%@ %ld %@",[error domain],(long)[error code],[[error userInfo] description]); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| else{ | ||||||||||||||||||||||||||||||||||||||||||
| NSLog(@"File removed."); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| [[NSFileManager defaultManager] copyItemAtPath:srcPath toPath:dstPath error:&error]; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if(error){ | ||||||||||||||||||||||||||||||||||||||||||
| NSLog(@"%@ %ld %@",[error domain],(long)[error code],[[error userInfo] description]); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| else if (isPkgFile) { | ||||||||||||||||||||||||||||||||||||||||||
| NSLog(@"Pkg File copied."); | ||||||||||||||||||||||||||||||||||||||||||
| [viewController installNewPackages]; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Remove the pkg file after installation | ||||||||||||||||||||||||||||||||||||||||||
| [[NSFileManager defaultManager] removeItemAtPath:dstPath error:&error]; | ||||||||||||||||||||||||||||||||||||||||||
| if(error){ | ||||||||||||||||||||||||||||||||||||||||||
| NSLog(@"%@ %ld %@",[error domain],(long)[error code],[[error userInfo] description]); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| else{ | ||||||||||||||||||||||||||||||||||||||||||
| NSLog(@"Installed Pkg file removed."); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| else if (isROMFile) { | ||||||||||||||||||||||||||||||||||||||||||
| NSLog(@"ROM File copied to Documents directory: %@", filename); | ||||||||||||||||||||||||||||||||||||||||||
| // Dismiss the "missing ROM" action sheet if it's showing and restart the emulator | ||||||||||||||||||||||||||||||||||||||||||
| [viewController checkForROMImage]; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| [url stopAccessingSecurityScopedResource]; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| if ([url.scheme isEqualToString:@"file"]) { | ||||||||||||||||||||||||||||||||||||||||||
| [self handleIncomingFile:url]; | ||||||||||||||||||||||||||||||||||||||||||
| return YES; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||||||||||
| [[UIApplication sharedApplication] openURL:url options:options completionHandler:nil]; | ||||||||||||||||||||||||||||||||||||||||||
| return YES; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| return NO; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+157
to
+168
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix unreachable code and reconsider URL forwarding logic. Line 167 ( - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
if ([url.scheme isEqualToString:@"file"]) {
[self handleIncomingFile:url];
return YES;
}
- else {
- [[UIApplication sharedApplication] openURL:url options:options completionHandler:nil];
- return YES;
- }
- return NO;
+ return NO;
}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - (void)applicationWillResignActive:(UIApplication*)application | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| [viewController stopEmulator]; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - (void)applicationDidBecomeActive:(UIApplication*)application | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| // Check if ROM was added while app was in background | ||||||||||||||||||||||||||||||||||||||||||
| // This will dismiss the missing ROM sheet if ROM is now available | ||||||||||||||||||||||||||||||||||||||||||
| [viewController checkForROMImage]; | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
175
to
+179
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Find the checkForROMImage method implementation
fd "\.mm$|\.h$" | xargs rg -A 15 "checkForROMImage" --color=never | head -100Repository: pguyot/Einstein Length of output: 5923 🏁 Script executed: #!/bin/bash
# Find the loadROMImage method
fd "\.mm$|\.h$" | xargs rg -A 10 "loadROMImage" --color=never | head -100Repository: pguyot/Einstein Length of output: 3724 🏁 Script executed: #!/bin/bash
# Check how viewController is initialized in the delegate
rg -A 20 "applicationDidFinishLaunching|viewController\s*=" app/iEinstein/Classes/iEinsteinAppDelegate.mm | head -80Repository: pguyot/Einstein Length of output: 1591 🏁 Script executed: #!/bin/bash
# Check the full context around line 175-179
sed -n '160,190p' app/iEinstein/Classes/iEinsteinAppDelegate.mmRepository: pguyot/Einstein Length of output: 951 🏁 Script executed: #!/bin/bash
# Find mLog initialization in iEinsteinViewController
rg "mLog\s*=" app/iEinstein/Classes/iEinsteinViewController.mm | head -20Repository: pguyot/Einstein Length of output: 127 🏁 Script executed: #!/bin/bash
# Find viewDidLoad and init methods in iEinsteinViewController to see initialization order
rg -A 30 "(viewDidLoad|^- \(id\)init)" app/iEinstein/Classes/iEinsteinViewController.mm | head -80Repository: pguyot/Einstein Length of output: 41 🏁 Script executed: #!/bin/bash
# Search for where mLog is declared and any guards around its usage
rg "mLog" app/iEinstein/Classes/iEinsteinViewController.hRepository: pguyot/Einstein Length of output: 71 🏁 Script executed: #!/bin/bash
# Find the context where mLog is initialized with TStdOutLog
rg -B 10 -A 5 "mLog = new TStdOutLog" app/iEinstein/Classes/iEinsteinViewController.mmRepository: pguyot/Einstein Length of output: 360 🏁 Script executed: #!/bin/bash
# Look at the full viewDidLoad and viewWillAppear methods
sed -n '1,500p' app/iEinstein/Classes/iEinsteinViewController.mm | rg -A 40 "viewDidLoad|viewWillAppear"Repository: pguyot/Einstein Length of output: 2681 🏁 Script executed: #!/bin/bash
# Check if there are any nil-safety checks or guards before checkForROMImage call
rg -B 5 "checkForROMImage" app/iEinstein/Classes/iEinsteinAppDelegate.mmRepository: pguyot/Einstein Length of output: 504 🏁 Script executed: #!/bin/bash
# Look for any initialization of viewController besides the storyboard assignment
rg "viewController" app/iEinstein/Classes/iEinsteinAppDelegate.mm | head -30Repository: pguyot/Einstein Length of output: 834 Add a nil check before calling While the iOS lifecycle typically ensures 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (![viewController allResourcesFound]) | ||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reset error before
copyItemAtPathto avoid logging stale errors.If
removeItemAtPath:fails (settingerror), thencopyItemAtPath:succeeds (not touchingerror), the stale error will still be logged at line 132-134, incorrectly suggesting the copy failed.if(error){ NSLog(@"%@ %ld %@",[error domain],(long)[error code],[[error userInfo] description]); } else{ NSLog(@"File removed."); } + error = nil; } [[NSFileManager defaultManager] copyItemAtPath:srcPath toPath:dstPath error:&error]; }📝 Committable suggestion
🤖 Prompt for AI Agents