Skip to content

Code audit: fix memory leaks, SQL formatting, and migration bug#9

Draft
rsharrott wants to merge 35 commits into
masterfrom
claude/audit-codebase-zbSn2
Draft

Code audit: fix memory leaks, SQL formatting, and migration bug#9
rsharrott wants to merge 35 commits into
masterfrom
claude/audit-codebase-zbSn2

Conversation

@rsharrott
Copy link
Copy Markdown
Contributor

Summary

Audit pass over the iOS Objective-C codebase (jFlash/Classes/AppSpecific/). This PR contains only the simple, high-confidence fixes. Larger architectural issues are listed below for separate decisions.

Fixes in this PR

Memory leaks

  • ActionBarViewController.shareWord[NSMutableArray new] and the UIActivityViewController were both leaked on every share invocation.
  • StudyViewController.dealloc — the retained delegate property was never released. Each instance leaked its delegate (and the comment in the header already flagged the design).
  • TweetWordAuthController.dealloc — same: retained delegate never released.

Database

  • UserHistoryPeer._recordResult: — replaced +[NSString stringWithFormat:]-built INSERT with a parameterized FMDB query. The old form also wrapped integers in single quotes ('%d'), which stored them with TEXT affinity in SQLite.
  • ExampleSentencePeer — converted retrieveExampleSentenceByPK, getExampleSentencesByCardId, sentencesExistForCardId, and searchSentencesForKeyword to parameterized queries via a new retrieveSentencesWithSQL:hydrate:arguments: overload.
  • ExampleSentencePeer.retrieveExampleSentenceByPK: now returns nil instead of crashing on -[NSArray objectAtIndex:0] when no row matches the id.

Migrations

  • UpdateManager._runMultipleSQLStatements: — the while (!feof(fh)) loop re-executed the previous SQL line whenever the final fgets hit EOF without producing a fresh line (the buffer still held the prior contents). Driven off fgets's return value now.

Test plan

  • Build for iOS (jFlash + cFlash targets).
  • Manual: search-results path (SearchViewControllerCardPeer.searchCardsForKeyword) — try a query that previously broke on ' characters.
  • Manual: study mode quiz/practice — record right/wrong answers (exercises UserHistoryPeer).
  • Manual: tap an example sentence on a card (exercises ExampleSentencePeer).
  • Manual: Share button on a card (exercises ActionBarViewController.shareWord — verify Activity sheet appears and dismisses cleanly under Instruments / Allocations).
  • Manual: fresh install on top of an old jFlash.db to exercise the migration runner.

Not in this PR — needs decision

See the audit summary in the conversation for details. Roughly:

  1. CardPeer._FTSSQLForKeyword: — the user's search keyword is concatenated into an FTS MATCH query. A query containing ' breaks the SQL today; this should be either parameterized or sanitized via FTS escape rules.
  2. Twitter / OAuth removalTweetWordAuthController and the bundled OAuthConsumer lib are dead code; Twitter v1 OAuth no longer works. Recommend deleting along with LWE_TWITTER_* constants.
  3. Delegate retain patternStudyViewController and TweetWordAuthController retain their delegates. Per Apple convention these should be assign/weak, but flipping them needs a sweep of callers.
  4. Deprecated UIWebViewCardViewController and TweetWordAuthController still use UIWebView (deprecated since iOS 12, removed in iOS 17/18 builds). Migrate to WKWebView (already done in ExampleSentencesViewController).
  5. JS string interpolation in WebViewsCardViewController._injectMeaningHTML: only escapes single quotes; backslashes and newlines in card meanings will break the JS. Low risk but fragile.
  6. Card.playerWithPluginManager: — returns [_player autorelease] while keeping the ivar. Caller must immediately retain or the ivar dangles. Refactor to a clean ownership model.
  7. NSNotificationCenter observer hygiene — most uses are on singletons (no real leak), but the block-based observer in jFlashAppDelegate deserves an audit if anything besides the app delegate ever uses that pattern.
  8. ASIHTTPRequest — listed as a submodule; deprecated since 2012. PluginManager uses it. Replace with NSURLSession.

https://claude.ai/code/session_01Gnm7rMhNx8tVssjNzYmvP1


Generated by Claude Code

rsharrott and others added 30 commits April 22, 2026 11:41
iOS 26 (Xcode 26.3) introduces mandatory UIApplicationSceneManifest and no
longer auto-loads NSMainNibFile, breaking the original NIB-based launch flow.

Changes:
- main.m: pass @"jFlashAppDelegate" to UIApplicationMain so UIKit creates
  the delegate before the scene fires (was nil in scene callback)
- jFlash-Info.plist: add UIApplicationSceneManifest pointing at LWESceneDelegate;
  remove NSMainNibFile keys to avoid double-load conflict
- jFlashAppDelegate.m: add LWESceneDelegate (UIWindowSceneDelegate) that creates
  a scene-backed UIWindow; load MainWindow.xib manually in
  didFinishLaunchingWithOptions: so IBOutlets are wired before any outlet-based
  code; defer window.rootViewController = tabBarController to
  _openUserDatabaseWithPlugins (after DB+plugins are ready) so viewDidLoad
  methods don't query cards before CARD_DB is attached
- XIBs/MainWindow.xib: change File's Owner from UIApplication to
  jFlashAppDelegate and move all outlet connections there; remove the now-
  redundant custom jFlashAppDelegate object; fix tabBarController delegate outlet
- HelpViewController.m: replace direct UIAlertView with UIAlertController
- Appirater.m: replace UIAlertView with UIAlertController
- Classes/Reusable/LWE: update submodule to commit that replaces LWEUIAlertView
  factory (UIAlertView) with UIAlertController presentation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
iOS 15+ introduces a transparent scrollEdgeAppearance by default, which causes
the window background to bleed through into the home-indicator safe area below
the tab bar. Explicitly configure UITabBarAppearance with the default opaque
background so the tab bar fills the safe area consistently.

Also set window.backgroundColor = black so the splash/loading phase
doesn't flash white on dark-theme devices.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two-part fix:

1. Set tabBar.translucent = NO and use configureWithOpaqueBackground
   so UIKit sizes child view controllers' views to end above the tab bar
   rather than extending underneath the new iOS 26 floating-glass tab bar.
   Without this, the glass/white region of the floating tab bar was visible
   between the action-bar buttons and the tab bar items.

2. Set StudyViewController.view.backgroundColor to match the action bar's
   gray (#E6E6E6) so that any residual gap shows a consistent color rather
   than the near-white pinkish default from the XIB.

Also removed the temporary diagnostic NSLog statements added during debugging.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add UILaunchScreen to Info.plist so iOS exits 320x568 compatibility
mode and renders at the device's native resolution. Update autoresizing
masks on root views and key subviews across all main XIBs (StudyView,
ActionBarViewController, CardViewController, ProgressBarViewController,
ExampleSentencesView, ProgressView, SearchView, AddStudySetView,
UserDetailsView) to widthSizable so layouts fill the full screen width
on current iPhones.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Push the top progress bar below the notch by repositioning it to
safeAreaInsets.top in viewSafeAreaInsetsDidChange instead of a
hardcoded y=20 that predates Face ID devices.

Evenly distribute action bar buttons across the full screen width
in viewDidLayoutSubviews rather than relying on autoresizing-mask
proportional layout, which broke when the screen widened from 320pt
to 390pt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Tab bar: isa-swap UITabBar to LWECenteredTabBar via object_setClass so
  items center vertically in the full bar height; XIB customClass is
  silently ignored by UIKit for tabBar properties, making this the only
  reliable approach
- Card layout: add CardViewController.layoutCardSubviews to position
  reading/headword at ~25% of card height (~30% from screen top) and
  extend the meaning webview to fill the remaining space down to the
  mood icon
- StudyViewController: fill card VC view to full container height
  (no vertical centering), call layoutCardSubviews on each layout pass,
  and push the reveal button below the headword area so the reading
  toggle is tappable without triggering the definition reveal
- Definition HTML: replace fixed-width table layout with flexbox so
  text centers correctly on all screen widths
- Study view labels: left-align card set name, right-align card count,
  both with 8pt symmetric edge padding

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace deprecated SenTestingKit with XCTest in all test files
- Update libz and Twitter framework references in project file
- Update submodule pointers and XIB metadata after Xcode resave
- Update sqlite3 subproject build settings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace old PNG images (practice-btn-*.png) with SF Symbol icons:
plus.circle.fill (blue/actions), checkmark.circle.fill (green/right),
xmark.circle.fill (red/wrong), archivebox.circle.fill (orange/bury it).

Root cause of prior failure: actionBarDidChangeMode: was calling
loadNibNamed:owner: which re-routed all IBOutlets to orphaned buttons
outside the view hierarchy, so hide/show calls and style changes
were applied to buttons the user never saw. Removed these redundant
NIB reloads — _setupSubviews already creates fresh instances.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
UIActionSheet was silently ignored on modern iOS. Replaced with
UIAlertController (action sheet style) with inline action handlers,
removing the now-unnecessary UIActionSheetDelegate conformance and
SVC_ACTION_* button index constants.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
FTS_DB (30MB) and EX_DB (52MB) are now included in the app bundle so
users get them immediately without a separate download. New installs
install all three bundle plugins on first launch; existing 1.8 users
pick them up via a 1.8→1.9 migration that registers the bundle plugins
directly in NSUserDefaults before the DB is opened.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaced hardcoded 315px/265px pixel widths (original iPhone era) with
fluid 100% widths and 14px body padding, and added a viewport meta tag
so the web view renders at device width rather than a fixed 320pt canvas.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Zeroed XIB left margin and removed body padding so content fills the
full viewport width. List number indentation (padding-left on ol) is
now the only visual offset from the edge.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace UIWebViewDelegate with WKNavigationDelegate
- Create WKWebView programmatically in viewDidLoad (WKWebView cannot
  be an IBOutlet in legacy XIBs); remove UIWebView from the XIB
- Replace shouldStartLoadWithRequest: with
  decidePolicyForNavigationAction:decisionHandler:
- Replace synchronous stringByEvaluatingJavaScriptFromString: with
  evaluateJavaScript:completionHandler:
- Remove UIWebView+LWENoBounces category; use scrollView.bounces = NO
- Link WebKit.framework in jFlash target

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Push scrollView below progress bar in viewSafeAreaInsetsDidChange so
  sentences start below the progress bar instead of behind it
- Set example sentences container to full scroll-page width instead of
  centering a 320pt-wide XIB frame, removing the phantom side margins
- Add 10px horizontal body padding in HTML so text and Read button have
  matching visual insets from both edges
- Fix _pluginDidInstall: version check (was == "1.1", should be != "1.1")
- Remove _updateSettingsFrom18to19 migration (bundled plugins are handled
  entirely by the first-load install path)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removed the hardcoded provisioning profile UUID
84DB2FA3-1C5B-44E3-961A-B7F863341332 from Debug, Release, and Beta
build configs. All three already had CODE_SIGN_STYLE = Automatic and
DEVELOPMENT_TEAM set, so Xcode will now manage the profile automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add [self.view setNeedsLayout] in _setupSubviews so viewDidLayoutSubviews
  fires after every study set change, resizing the new cardViewController.view
  (loaded from a 320x278 NIB) to fill its container correctly
- Clean up card HTML templates: remove legacy -webkit-flex centering,
  use simpler padding-top approach that works with our explicit frame layout
- Switch Info.plist bundle ID to $(PRODUCT_BUNDLE_IDENTIFIER) and remove
  obsolete orientation/icon/statusbar keys

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This app was designed for light mode only. On dark mode iPhones,
systemBackgroundColor (used in ActionBarViewController) resolved to
pure black, making the action bar invisible. Forcing light mode on
the window fixes all system color adaptations app-wide without
needing to patch individual color references.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CardTagTest.m: 15 new tests covering card retrieval, hydration, tag
  membership, and UserHistoryPeer level transitions (correct/wrong/bury)
- TagTest.m: 6 new tests for tag properties, editability, CRUD, and
  retrieval by name and ID
- PluginTest.m: 7 new tests for plugin type detection (database/directory)
  and version comparison
- JFlashSearchTest.m: 5 new tests for kana/English/nonsense search and
  keywordIsReading/keywordIsHeadword classification
- JFlashPluginMigrationTest.m: 2 new tests for unknown-key resilience and
  cross-format version comparison

Also fixes jFlashTest build: adds missing source files to the test target
(UserHistoryPeer, UserPeer, User, DisplaySearchedSentenceViewController,
JREngage) and removes the legacy RunUnitTests script phase that referenced
a tool removed in modern Xcode.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tapping the speaker icon next to the headword reads the word aloud
using AVSpeechSynthesizer with the best available ja-JP voice:
premium (iOS 16+) → enhanced → standard fallback.

The button is positioned to the right of the headword row in
layoutCardSubviews and is visible before card reveal, matching
the pattern of the reading-toggle button. Wrapped in LWE_JFLASH
so the cFlash audio-plugin path is unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Splits "kana - romaji" reading label text and speaks only the kana
portion, giving the TTS engine the exact pronunciation rather than
relying on it to interpret kanji.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Follows the existing fake-URL interception pattern used by the Read
and Add buttons. Each sentence gets an inline 🔊 button whose href
encodes the sentence ID; tapping it looks up the stored sentenceJa
text and speaks it via AVSpeechSynthesizer with the best available
ja-JP voice (premium → enhanced → standard).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Instead of narrowing the headword container to reserve fixed space on
the right, the scroll container remains full-width so center alignment
is unaffected. _updateSpeakBtnPosition computes the visual right edge
of the rendered text (containerCenter + textWidth/2) and places the
36pt button 6pt to its right. Called from both layoutCardSubviews
(on layout/set-change) and _prepareView: (on every card change) so
position tracks the current word's actual rendered width.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The 🔊 emoji was written to the source file as a corrupt 3-byte
sequence (0xF0 lead byte dropped). Replace with the HTML entity
&#x1F50A; which is pure ASCII in the source and decodes correctly
in WKWebView.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaced corrupted emoji (&#x1F50A;) with inline SVG speaker icon (pure
ASCII, reliable WebKit rendering). Moved button inside showWordsDiv so
it appears to the right of the Read button. Handles both plugin v1.1
(standalone float-right) and v1.2 (alongside Read button) cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Grow SF Symbol icon from 34pt to 44pt to better fill the bar height
- Add imageEdgeInsets to shift icon up, leaving clear space for labels
- distributeButtonsEvenly: each button now fills an equal share of the
  full bar width (floor(width/n)) rather than using fixed widths + gaps
- Apply modern SF Symbol styling to prevCardBtn/nextCardBtn in browse
  mode (chevron.left/right.circle.fill, gray tint with "prev"/"next"
  labels), replacing the legacy practice-btn-last/next PNG images
- viewDidLayoutSubviews: include prev/next in label-positioning loop

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add vertical-align:middle to the inline SVG so the speaker icon sits
at the same midline as the Read button text instead of dropping to baseline.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Drop APP_TWITTER and APP_FACEBOOK constants and their extern declarations
- Remove social section from JapaneseSettingsDataSource and
  ChineseSettingsDataSource return arrays (both update-available paths)
- Remove cell rendering and tap-handling branches for Twitter/Facebook
- Remove UIWebView delegate methods that were only used to load the
  Twitter/Facebook URLs
- Drop UIWebViewDelegate conformance from SettingsViewController

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Drop the kLWEBackupSection enum value and reduce NUM_SECTIONS in both
  LWE_JUNIOR and non-JUNIOR paths
- Remove all backup/restore UI: section header, cell rendering, row
  count, tap handling (Backup Now / Restore Now / Logout rows)
- Remove backup and restore methods, and all LWEBackupManagerDelegate
  callbacks (statusDidChange, currentProgress, didBackup, didRestore,
  didFail×2)
- Remove kBackupConfirmationAlertTag / kRestoreConfirmationAlertTag and
  their alertView:clickedButtonAtIndex: branches
- Drop BackupManager property from StudySetViewController header/impl
- Remove BackupManager.h/m and LWEJanrainLoginManager.h/m from the
  project (pbxproj PBXFileReference, PBXGroup, and all Sources build
  phases) and delete the files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… screens

- Remove Flurry library (FlurryLib dir, pbxproj entries, LWEAnalytics dead code)
- Remove Backup Custom Sets and Feedback from Help menu
- Fix Change Difficulty segmented control overlapping nav bar: move into tableHeaderView
- Fix Get Updates button/label overlapping nav bar: move into tableHeaderView
- Both settings screens now span full screen width with flexible autoresizing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove APP_TEXT_SIZE setting and its Normal/Large/Huge constants; map
UIContentSizeCategoryXxx to CSS px and scale factors at runtime instead.
Subscribe to UIContentSizeCategoryDidChangeNotification to reload cards
when the user changes system text size. Fix hardcoded line-height values
in WKWebView HTML templates (21px/32px → 1.4) so meaning text never
overlaps at accessibility sizes. Apply UITableViewAutomaticDimension
across Settings, StudySet, Help, Plugin, and Search screens so list
cells grow cleanly with large Dynamic Type sizes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rsharrott and others added 5 commits April 25, 2026 10:18
Remove Twitter integration references and Follow us on Twitter links.
Fix typo "please us know" → "please let us know" in Corrections.
Replace "tweet the word" with "share the card" in Practice and Browse.
Fix CFlash Integration page saying "launch jflash" → "launch cflash".
Remove outdated screenshots whose UI changed (card buttons, browse
buttons, difficulty screen).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Memory leaks
- ActionBarViewController.shareWord: NSMutableArray (created with
  +new) and the UIActivityViewController were both leaked on every
  share. Use +array and autorelease the controller after present.
- StudyViewController.dealloc: the retained delegate was never
  released, so each instance leaked its delegate.
- TweetWordAuthController.dealloc: same — retained delegate never
  released.

Database
- UserHistoryPeer.recordResult: replace -[NSString initWithFormat:]
  built INSERT with a parameterized FMDB query. The previous form
  also wrapped integers in single quotes, storing them with TEXT
  affinity in SQLite.
- ExampleSentencePeer: convert all of retrieveExampleSentenceByPK,
  getExampleSentencesByCardId, sentencesExistForCardId, and
  searchSentencesForKeyword to parameterized queries via a new
  retrieveSentencesWithSQL:hydrate:arguments: variant.
  retrieveExampleSentenceByPK now returns nil rather than crashing
  on -[NSArray objectAtIndex:0] when no row matches.

Migrations
- UpdateManager._runMultipleSQLStatements: the `while (!feof(fh))`
  loop re-ran the previous SQL line whenever the final fgets hit
  EOF without producing a fresh line, because str_buf still held
  the prior contents. Drive the loop off fgets's return value.

https://claude.ai/code/session_01Gnm7rMhNx8tVssjNzYmvP1
Twitter API v1 OAuth no longer works and the share-from-card path now
goes through UIActivityViewController; the bespoke Twitter sign-in
flow is dead code.

- Delete TweetWordAuthController + its three XIBs.
- Delete the bundled OAuthConsumer library.
- ActionBarViewController.shareWord: drop -getTweetWord and the
  Twitter-character-limit math; build the share string directly from
  headword/reading/meaning. The activity sheet truncates per-target
  itself.
- Constants: drop LWE_TWITTER_CONSUMER_KEY, LWE_TWITTER_PRIVATE_KEY,
  LWE_TWITTER_HASH_TAG (both jFlash and cFlash variants) and
  LWE_TWITTER_MAX_CHARS.
- Remove the unused Twitter.framework reference from the Xcode
  project. The framework was listed in the Frameworks group but never
  linked.

Orphaned twitter-bird*.png / twitter-icon*.png assets remain in
jFlash/Assets/ and project.pbxproj. Removing PBXBuildFile rows by
hand is risky without an Xcode build to verify, so they're left for
a follow-up cleanup in Xcode itself.

https://claude.ai/code/session_01Gnm7rMhNx8tVssjNzYmvP1
UIWebView has been deprecated since iOS 12 and is unavailable in
modern iOS releases, so the XIB-instantiated UIWebView in
CardViewController, HelpWebViewController, and ModalTaskViewController
no longer works. Apply the same pattern already used by
ExampleSentencesViewController:

- Each XIB now contains a plain UIView placeholder (the IBOutlet was
  renamed *Container in code and XIBs).
- viewDidLoad creates a WKWebView, sets it up (clear background,
  bounces=NO, autoresizing fill), and adds it as a subview of the
  container.
- Delegate callbacks switch from UIWebViewDelegate to
  WKNavigationDelegate (webViewDidFinishLoad: -> webView:didFinishNavigation:).
- stringByEvaluatingJavaScriptFromString: -> evaluateJavaScript:completionHandler:.
- HelpWebViewController now uses loadFileURL:allowingReadAccessToURL:
  for local help/*.html files, which WKWebView requires.

Side cleanups:

- Drop the UIWebView+LWENoBounces.h imports and uses; WKWebView
  exposes the underlying scrollView directly.
- CardViewController._injectMeaningHTML: also escape backslash, CR,
  and newline before splicing into the JS string so card meanings
  containing those characters don't break the literal.

Legacy IB metadata in cFlash/CardViewController-EtoJ.xib (the class
list and outlet candidate-class strings) still mentions UIWebView;
that's plist metadata only, not a runtime instance, and Xcode will
quietly update it the next time the XIB is opened.

https://claude.ai/code/session_01Gnm7rMhNx8tVssjNzYmvP1
ASIHTTPRequest was deprecated in 2012 and PluginManager imported its
header but never actually called any of its API. The real network
fetch was a synchronous +[NSDictionary dictionaryWithContentsOfURL:]
on a background thread spun up by performSelectorInBackground:, with
no error reporting.

- Drop the unused ASIHTTPRequest.h import.
- Replace -checkNewPluginsAsynchronous: + private
  -_retrievePlistFromServer with a single
  -checkNewPluginsWithCompletion: that uses
  +[NSURLSession sharedSession] -dataTaskWithURL:completionHandler:
  and parses the response with NSPropertyListSerialization.
- The completion handler hops back to the main queue before
  touching NSUserDefaults, mutating self.downloadablePlugins, or
  invoking the caller's block.
- jFlashAppDelegate's startup check passes a nil completion.
- PluginSettingsViewController's manual "check now" button moves
  the alert / table reload / activity-view dismissal into the
  completion block, so the main thread no longer blocks waiting on
  the network round-trip.

The asi-http-request submodule and its build entries in
project.pbxproj are still present but no longer referenced by any
app code; they can be removed in a follow-up Xcode change.

https://claude.ai/code/session_01Gnm7rMhNx8tVssjNzYmvP1
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.

2 participants