Skip to content

Conversation

@rbruels
Copy link

@rbruels rbruels commented Dec 13, 2025

(This PR builds on (and supercedes) awesome work done by @AlohaYos in PR #189. 🤝)

This PR adds iOS file sharing support and removes the need to plug your device into your Mac. Users can now import the all-important .rom file and additional .pkg files via the iOS share sheet or the Files app (which now shows iOSEinstein's Documents folder within the "On My iPhone" section).

I shuffled around the ROM loading a bit so that we can detect the ROM at any point in the app lifecycle (so the "Quit Einstein" alert will dismiss if the user didn't press the button but instead went to go load a ROM... which I did a number of times 😆).

Fixes #48.

Simulator Screenshot - iPhone 17 Pro Max - 2025-12-13 at 15 47 35 Screenshot 2025-12-13 at 3 48 26 PM Simulator Screenshot - iPhone 17 Pro Max - 2025-12-13 at 15 47 13

Summary by CodeRabbit

  • New Features

    • Added support for opening Newton Package Data and ROM Image files directly from Files app.
    • Enabled document browser integration for easier file management.
    • Improved ROM image detection and handling during app launch and resume.
  • Bug Fixes

    • Enhanced error handling for missing ROM files with clearer user alerts.
    • Refined file processing workflow for better stability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 13, 2025

Walkthrough

The pull request adds iOS document handling capabilities to the iEinstein app. It configures the app to accept Newton ROM images and package files through the Files app by updating Info.plist files with document type declarations and implementing file handlers in the app delegate and view controller to process incoming files.

Changes

Cohort / File(s) Summary
Document Type Configuration
Resources/iOSEinstein Storyboards-Info.plist, Resources/iOSEinstein-Info.plist
Added document type declarations for Newton ROM images (com.newton-inc.rom) and Newton packages (com.newton-inc.pkg); enabled document browser support and in-place document opening via LSSupportsOpeningDocumentsInPlace and UISupportsDocumentBrowser keys.
File Handling & Launch
app/iEinstein/Classes/iEinsteinAppDelegate.mm
Introduced three new methods: + (void)initialize to register default user preferences, - (void)handleIncomingFile:(NSURL *)url to process incoming ROM and package files with copying and installation logic, and - (BOOL)application:openURL:options: to route file URLs to the handler. Extended applicationDidBecomeActive: to check for ROM availability on resume.
ROM Image Loading & Management
app/iEinstein/Classes/iEinsteinViewController.h, app/iEinstein/Classes/iEinsteinViewController.mm
Added instance variable mMissingROMAlertView and four new methods: - (BOOL)checkForROMImage to verify and load ROM availability, - (TROMImage*)loadROMImage to discover and load ROM files, - (void)alertView:clickedButtonAtIndex: for alert delegation, and - (void)dismissMissingROMAlertAndReset for cleanup. Replaced action sheet-based ROM absence flow with UIAlertView; refactored initEmulator to use extracted ROM loading helper.

Sequence Diagram

sequenceDiagram
    participant FileApp as Files App
    participant AppDel as App Delegate
    participant FileIO as Filesystem
    participant ViewController as View Controller
    participant Emulator as Emulator

    FileApp->>AppDel: openURL (ROM or .pkg file)
    activate AppDel
    AppDel->>AppDel: handleIncomingFile:url
    AppDel->>FileIO: Acquire security scope
    AppDel->>FileIO: Resolve Documents directory
    alt File is ROM
        AppDel->>FileIO: Copy ROM to destination
        AppDel->>ViewController: checkForROMImage
        activate ViewController
        ViewController->>FileIO: Discover/load ROM
        ViewController->>Emulator: Load ROM image
        ViewController->>Emulator: Reset emulator
        deactivate ViewController
    else File is Package
        AppDel->>FileIO: Copy package to destination
        AppDel->>ViewController: Install packages
        AppDel->>FileIO: Remove copied file
    end
    AppDel->>FileIO: Release security scope
    deactivate AppDel
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • File security and lifecycle: Review error handling in handleIncomingFile:url for file operations and security-scoped resource acquisition/release.
  • ROM loading refactoring: Verify the extracted loadROMImage method correctly integrates with initEmulator and maintains emulator state consistency.
  • Alert view management: Check that mMissingROMAlertView lifecycle is properly managed across initialization, dismissal, and deallocation to prevent leaks.
  • File operation logic: Validate file copying, deletion, and extension-based type detection for ROM vs. package files.

Poem

🐰✨ Files hop through the browser door,
ROM images dance to the emulator's core,
Packages unpacked with a flourish and cheer,
Newton's dreams brought crystal clear!
Documents in place, the app takes flight—
A rabbit's work makes everything right! 🚀

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: enabling file loading from the Files app and share sheet for ROMs and packages.
Linked Issues check ✅ Passed The PR successfully addresses issue #48 by enabling document browser support, making the app directory visible to iOS Files app, and supporting ROM/package file loading.
Out of Scope Changes check ✅ Passed All changes are directly scoped to file sharing functionality: Info.plist document type configurations, file handling in app delegate, ROM detection logic, and alert handling.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@rbruels rbruels force-pushed the support-file-sharing-from-ios branch from 14769ea to b41b12a Compare December 13, 2025 23:46
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (2)
app/iEinstein/Classes/iEinsteinViewController.h (1)

50-51: Consider migrating to UIAlertController (optional).

UIAlertView has been deprecated since iOS 9. While it still works, consider migrating to UIAlertController for future compatibility. This is consistent with the existing use of UIActionSheet in the codebase, so this could be addressed as part of a broader modernization effort.

app/iEinstein/Classes/iEinsteinAppDelegate.mm (1)

45-46: Remove unnecessary synchronize call.

registerDefaults: only sets in-memory defaults for keys that haven't been set by the user—it doesn't write to disk. Calling synchronize here has no effect and is generally unnecessary in modern iOS.

 	[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
-	[[NSUserDefaults standardUserDefaults] synchronize];
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a29e0a0 and b41b12a.

📒 Files selected for processing (5)
  • Resources/iOSEinstein Storyboards-Info.plist (3 hunks)
  • Resources/iOSEinstein-Info.plist (1 hunks)
  • app/iEinstein/Classes/iEinsteinAppDelegate.mm (2 hunks)
  • app/iEinstein/Classes/iEinsteinViewController.h (2 hunks)
  • app/iEinstein/Classes/iEinsteinViewController.mm (5 hunks)
🔇 Additional comments (5)
Resources/iOSEinstein Storyboards-Info.plist (1)

11-33: LGTM! Well-structured document type declarations.

The document types and UTI declarations are correctly configured:

  • Proper LSHandlerRank: Owner claims ownership for ROM and pkg files
  • Case-insensitive file extensions covered (rom/ROM, pkg/PKG)
  • UTIs conform to public.data as expected for binary file types

Also applies to: 78-121

app/iEinstein/Classes/iEinsteinViewController.mm (3)

135-147: LGTM! Clean dismissal and reset flow.

The method properly dismisses the alert, releases resources (under manual memory management), and triggers emulator reset to reinitialize with the newly available ROM.


202-220: Nice approach for Files app visibility.

Creating a placeholder file to ensure the Documents folder appears in the Files app is a good UX improvement. This helps users locate where to place ROM files.


360-372: LGTM! Clean extraction of ROM loading logic.

The ROM loading logic is now properly encapsulated in loadROMImage, making the code more maintainable and enabling reuse from checkForROMImage.

Resources/iOSEinstein-Info.plist (1)

36-41: This file is not actively used in the build configuration. The Xcode project uses iOSEinstein Storyboards-Info.plist for the iOS Einstein app, not this file. The Storyboards plist already contains the necessary CFBundleDocumentTypes and UTExportedTypeDeclarations for handling Newton Package Data and ROM Image files. No changes are needed here.

Comment on lines +119 to +134
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]);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Reset error before copyItemAtPath to avoid logging stale errors.

If removeItemAtPath: fails (setting error), then copyItemAtPath: succeeds (not touching error), 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

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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]);
}
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.");
}
error = nil;
}
[[NSFileManager defaultManager] copyItemAtPath:srcPath toPath:dstPath error:&error];
}
if(error){
NSLog(@"%@ %ld %@",[error domain],(long)[error code],[[error userInfo] description]);
}
🤖 Prompt for AI Agents
In app/iEinstein/Classes/iEinsteinAppDelegate.mm around lines 119 to 134, the
NSError *error value from removeItemAtPath: can remain set and later be
misinterpreted after copyItemAtPath:—reset the error to nil before calling
copyItemAtPath: (or declare and use a separate NSError variable for the copy
call) and check/log each call's error immediately after that specific API
returns so stale errors are never logged for a subsequent operation.

Comment on lines +157 to +168
- (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;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix unreachable code and reconsider URL forwarding logic.

Line 167 (return NO) is unreachable since both branches return YES. Additionally, forwarding unknown URL schemes to openURL: in the else branch may cause unexpected behavior or infinite loops if the system routes it back.

 - (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

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- (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;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
if ([url.scheme isEqualToString:@"file"]) {
[self handleIncomingFile:url];
return YES;
}
return NO;
}

Comment on lines 175 to +179
- (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];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the checkForROMImage method implementation
fd "\.mm$|\.h$" | xargs rg -A 15 "checkForROMImage" --color=never | head -100

Repository: 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 -100

Repository: 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 -80

Repository: 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.mm

Repository: pguyot/Einstein

Length of output: 951


🏁 Script executed:

#!/bin/bash
# Find mLog initialization in iEinsteinViewController
rg "mLog\s*=" app/iEinstein/Classes/iEinsteinViewController.mm | head -20

Repository: 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 -80

Repository: 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.h

Repository: 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.mm

Repository: 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.mm

Repository: 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 -30

Repository: pguyot/Einstein

Length of output: 834


Add a nil check before calling checkForROMImage in applicationDidBecomeActive.

While the iOS lifecycle typically ensures viewController and its mLog are initialized before this method runs, the code lacks defensive guards. Consider checking that viewController is non-nil and initialized before proceeding, or add a nil check within loadROMImage to guard mLog access.

🤖 Prompt for AI Agents
In app/iEinstein/Classes/iEinsteinAppDelegate.mm around lines 175 to 179, the
code calls [viewController checkForROMImage] without verifying viewController is
non-nil which can lead to messaging nil-dependent state; add a defensive nil
check before invoking the method (for example, if (viewController) {
[viewController checkForROMImage]; }) or, alternatively, add a nil guard inside
loadROMImage to ensure mLog is valid before use so the call is safe when
viewController or its mLog is not yet initialized.

Comment on lines +57 to +59
- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
[[UIApplication sharedApplication] performSelector:@selector(terminateWithSuccess)];
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Using private API terminateWithSuccess will cause App Store rejection.

terminateWithSuccess is a private API. Apps using private APIs are rejected from the App Store, which directly conflicts with the PR objective of making the app suitable for the App Store (Issue #48).

Consider using exit(0) as a fallback (still discouraged by Apple) or redesigning the flow to hide the app instead of terminating (e.g., show a persistent "ROM required" screen).

🤖 Prompt for AI Agents
In app/iEinstein/Classes/iEinsteinViewController.mm around lines 57-59, the
alert handler uses the private API terminateWithSuccess which will cause App
Store rejection; remove the performSelector:@selector(terminateWithSuccess) call
and instead either (preferred) dismiss the alert and present a persistent UI
state (e.g., push or present a "ROM required" modal/fullscreen view that
prevents further use until resolved) or (if absolutely unavoidable and
documented) call exit(0) as a last-resort fallback with a comment warning about
App Store risks; ensure the replacement runs on the main thread and cleanly
disables or hides interactive controls so the app does not silently terminate
using private APIs.

Comment on lines +130 to +133
mMissingROMAlertView = [[UIAlertView alloc]
initWithTitle:@"Newton ROM not found!" message:message delegate:self cancelButtonTitle:nil otherButtonTitles:@"Quit Einstein", nil];
[mMissingROMAlertView show];
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Potential memory leak if alert is shown multiple times.

If explainMissingROM: is called while mMissingROMAlertView is already showing, the old alert reference is overwritten without being dismissed or released, causing a leak.

+	if (mMissingROMAlertView) {
+		return; // Already showing
+	}
+
 	mMissingROMAlertView = [[UIAlertView alloc]
 							  initWithTitle:@"Newton ROM not found!" message:message delegate:self cancelButtonTitle:nil otherButtonTitles:@"Quit Einstein", nil];
 	[mMissingROMAlertView show];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mMissingROMAlertView = [[UIAlertView alloc]
initWithTitle:@"Newton ROM not found!" message:message delegate:self cancelButtonTitle:nil otherButtonTitles:@"Quit Einstein", nil];
[mMissingROMAlertView show];
}
if (mMissingROMAlertView) {
return; // Already showing
}
mMissingROMAlertView = [[UIAlertView alloc]
initWithTitle:@"Newton ROM not found!" message:message delegate:self cancelButtonTitle:nil otherButtonTitles:@"Quit Einstein", nil];
[mMissingROMAlertView show];
}
🤖 Prompt for AI Agents
In app/iEinstein/Classes/iEinsteinViewController.mm around lines 130-133, the
new UIAlertView is assigned to mMissingROMAlertView without handling any
existing alert, which leaks if explainMissingROM: is called while an alert is
already shown; before creating/assigning a new alert, check if
mMissingROMAlertView is non-nil and either dismiss it (call
dismissWithClickedButtonIndex:animated: if it's visible) or release it (and set
its delegate to nil) and then set mMissingROMAlertView = nil, then create and
show the new alert and store it in mMissingROMAlertView to ensure the previous
alert is properly dismissed/released.

Comment on lines +149 to +161
- (TROMImage*)loadROMImage
{
// Create the ROM.
TROMImage* romImage = nil;
NSString* einsteinRExPath = nil;
NSBundle* thisBundle = [NSBundle mainBundle];

if (!(einsteinRExPath = [thisBundle pathForResource:@"Einstein" ofType:@"rex"]))
{
//[self abortWithMessage: @"Couldn't load Einstein REX"];
mLog->LogLine("Couldn't load Einstein REX");
return nil;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Potential null pointer dereference on mLog.

loadROMImage assumes mLog is initialized (line 159), but checkForROMImage can be called from applicationDidBecomeActive: before initEmulator creates mLog. This will crash when the Einstein REX isn't found.

Add a null check:

 	if (!(einsteinRExPath = [thisBundle pathForResource:@"Einstein" ofType:@"rex"]))
 	{
 		//[self abortWithMessage: @"Couldn't load Einstein REX"];
-		mLog->LogLine("Couldn't load Einstein REX");
+		if (mLog) {
+			mLog->LogLine("Couldn't load Einstein REX");
+		}
 		return nil;
 	}
🤖 Prompt for AI Agents
In app/iEinstein/Classes/iEinsteinViewController.mm around lines 149 to 161, the
method loadROMImage dereferences mLog when logging the missing Einstein REX path
but mLog may be nil if checkForROMImage is invoked before initEmulator; update
the code to check whether mLog is non-null before calling mLog->LogLine and, if
mLog is nil, use a safe fallback (e.g., NSLog or no-op) so no dereference
occurs; ensure the function returns nil afterwards as before.

Comment on lines +224 to 242
- (BOOL)checkForROMImage
{
// If we have a ROM already, do nothing
if (mROMImage) {
return YES;
}

// Try loading the ROM
mROMImage = [self loadROMImage];
if (mROMImage) {
if (mMissingROMAlertView) {
// ROM now exists and action sheet is showing - dismiss it and reset
[self dismissMissingROMAlertAndReset];
}
return YES;
}

return NO;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add guard for uninitialized state.

checkForROMImage can be called from applicationDidBecomeActive: before initEmulator runs (when ROM was previously missing). In this state, mLog is NULL, causing a crash in loadROMImage. Consider adding a guard:

 - (BOOL)checkForROMImage
 {
+	// Can't load ROM if log isn't initialized (initEmulator hasn't run)
+	if (!mLog) {
+		return NO;
+	}
+
 	// If we have a ROM already, do nothing
 	if (mROMImage) {
 		return YES;
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- (BOOL)checkForROMImage
{
// If we have a ROM already, do nothing
if (mROMImage) {
return YES;
}
// Try loading the ROM
mROMImage = [self loadROMImage];
if (mROMImage) {
if (mMissingROMAlertView) {
// ROM now exists and action sheet is showing - dismiss it and reset
[self dismissMissingROMAlertAndReset];
}
return YES;
}
return NO;
}
- (BOOL)checkForROMImage
{
// Can't load ROM if log isn't initialized (initEmulator hasn't run)
if (!mLog) {
return NO;
}
// If we have a ROM already, do nothing
if (mROMImage) {
return YES;
}
// Try loading the ROM
mROMImage = [self loadROMImage];
if (mROMImage) {
if (mMissingROMAlertView) {
// ROM now exists and action sheet is showing - dismiss it and reset
[self dismissMissingROMAlertAndReset];
}
return YES;
}
return NO;
}
🤖 Prompt for AI Agents
In app/iEinstein/Classes/iEinsteinViewController.mm around lines 224 to 242,
checkForROMImage currently calls loadROMImage even when the controller/emulator
hasn't been initialized (mLog is NULL), which leads to a crash; add a guard at
the top of checkForROMImage to return NO if the emulator state required by
loadROMImage isn't ready (for example if mLog is nil or an explicit
"initialized" flag is false) so loadROMImage is not invoked prematurely, and
keep existing logic to load/dismiss alerts only after the guard passes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

iOS: making Einstein directory visible to browser

1 participant