iOS: file-only :inet_db lookup by default in Mob.App.start/0 - #14
Closed
C-Sinclair wants to merge 1 commit into
Closed
iOS: file-only :inet_db lookup by default in Mob.App.start/0#14C-Sinclair wants to merge 1 commit into
C-Sinclair wants to merge 1 commit into
Conversation
iOS sandboxes execve of any binary the app didn't get a special pass for, and BEAM's default :native hostname resolver spawns the inet_gethost port program — so the first Node.connect / :erpc.call / gen_tcp.connect/3 with a binary host crashed with :badarg before this. The sim hits the same failure for a related-but-distinct reason (inet_gethost isn't where BEAM expects in the mob iOS-sim OTP layout). Mob.App.configure_ios_inet_db/0 sets the lookup chain to [:file] and seeds localhost. Called as the first line of the macro-generated start/0 so app on_start/0 never has to think about it. Gated on :mob_nif.platform() == :ios (host BEAM and Android untouched); guarded with try/rescue so the NIF-not-loaded case (host test BEAM) doesn't crash. Composes cleanly with Mob.DNS.configure_pure_beam/1 — apps that need outbound DNS layer it on top to upgrade [:file] → [:file, :dns]; the file-table entries seeded here stay ahead and keep winning.
GenericJam
commented
May 20, 2026
Owner
Thanks @C-Sinclair — landed as 11752a4 in mob 0.6.15 with your authorship preserved. CHANGELOG resolution merged both your The framework now owns the |
pshoukry pushed a commit
to pshoukry/mob
that referenced
this pull request
Sep 9, 2026
…ixed (mob_new + mob_dev companion commits) Four small lost-in-the-shuffle items closed in this batch. All four were held up by Phase 2 work touching the same files (GenericJam#1/GenericJam#2/GenericJam#4 in live_view_patcher.ex; GenericJam#5 in native_build.ex). GenericJam#1 — Phoenix LiveReload mac_listener warnings: code_reloader/watchers/ live_reload disabled in on-device endpoint config. GenericJam#2 — esbuild/tailwind version-not-configured warnings: versions set via Application.put_env in mob_app.ex before ensure_all_started. GenericJam#4 — port 4200 collisions across multiple Mob LV apps: per-app hash into 4200..4999 via :erlang.phash2(:<app>, 800). GenericJam#5 — deploy auto-pick of iPhone over sim was silent: prints the --device <short-id> alternative when both are connected. GenericJam#3 (WS→longpoll fallback in WKWebView) is investigation, not a fix — deferred. GenericJam#6-GenericJam#11 are larger work (OTP rebuild, AX modifiers, Compose semantics walker, Android 17 SELinux patch). GenericJam#12, GenericJam#13 already fixed earlier. GenericJam#14 is moderate — sim node naming reconciliation between mob_dev's connect.ex and mob_beam.m, deferred.
pshoukry pushed a commit
to pshoukry/mob
that referenced
this pull request
Sep 9, 2026
…d-around GenericJam#7 + GenericJam#8 — `MobSlider` and `MobToggle` in MobRootView.swift gained the SwiftUI AX modifiers SwiftUI doesn't apply by default (.accessibilityAdjustableAction with default step (max-min)/10 for the slider; .accessibilityLabel(label) for the toggle). Mob.Test end-to-end driving works after these. GenericJam#14 — defensive fallback in MobDev.Connector. When the primary node name times out the connector now also tries the alternate `<app>_ios@127.0.0.1` form (without the udid suffix). The connected Device.node is updated to whichever responded so downstream RPC calls use the correct address. The root cause (mob_beam.m sometimes not seeing SIMULATOR_UDID) is captured in the resolution note for a future investigation. Remaining: GenericJam#3 (WebSocket→longpoll, investigation), GenericJam#6 (16 KB page alignment, OTP rebuild), GenericJam#9 (Alert OK button, UIKit deep dive), GenericJam#10 (Android 17 SELinux, OTP source patch), GenericJam#11 (Android Compose semantics walker, ~200 lines Kotlin).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Mob.App.start/0now switches:inet_db's lookup chain to[:file]and seedslocalhoston iOS, before any user code runs. The firstNode.connect/:erpc.call/gen_tcp.connect/3with a binary host no longer crashes the calling process with:badarg.Why
BEAM's default
:nativehostname resolution spawns theinet_gethostport program. iOS's app sandbox forbidsexecveof any binary the app didn't get a special pass for, so the spawn fails categorically on device. The simulator hits the same failure for a related-but-distinct reason —inet_gethostdoesn't live at the path BEAM expects under the mob iOS-sim OTP layout. Either way, the lookup dies and any caller through:inet.getaddr/2(distribution, RPC, TCP-by-name) gets:badargand exits.Every iOS mob app today has to do this dance manually in
on_start/0before anything touches a hostname:Easy to forget, impossible to test for, and bites every new consumer the first time they call
:erpc.call. The framework should own this.Composability with
Mob.DNSPure addition.
Mob.DNS.configure_pure_beam/1keeps working — it upgrades[:file]→[:file, :dns]and seeds fallback nameservers. The file-table entries this PR adds stay first in the chain and keep winning, so the two layers compose:[:file], distribution + local-loopback TCP work. No DNS.Mob.DNS.configure_pure_beam/1for outbound HTTP — chain becomes[:file, :dns], fallback nameservers (Google + Cloudflare by default) handle public hosts.Mob.DNS.resolve/1for VPN / mDNS / search-domain semantics — Apple resolver via NIF, result seeded in the file table, always wins because:fileis first.Apps that want the default OS resolver back (and were somehow getting away with it on iOS) can call
:inet_db.set_lookup([:native])in their ownon_start/0, which runs afterstart/0.Why
[:file]not[:file, :dns]by defaultConservative — the irreducible fix is preventing the
inet_gethostspawn. Adding:dnsto the framework default would mean every iOS app pays for fallback-nameserver state it may not use, and apps that talk to an internal-only backend on a fixed IP get a slightly-noisierinet_db.Mob.DNS.configure_pure_beam/1is the right opt-in for apps that need DNS; the framework just guarantees the crash doesn't happen.Test plan
mix test— 798 passed (27 doctests, 771 tests), 43 excluded. Newtest/mob/app_test.exsverifies the host-BEAM (NIF-unloaded) path is a no-op and that the function is idempotent.mix format --check-formatted— cleanmix credo --strict— clean (952 mods/funs, 0 issues)mix compile --warnings-as-errors— cleanmix erlfmt --check src/— clean:erpc.callfrom a sim app crashes withinet_gethostopen_port:badarg, and with the fix the same call succeeds.Related
Companion to the other small contributions in this series —
text-field-secure(#12),fix/ios-column-fill-height,scroll-on-refresh,nav-transition-override. Each stands alone; land in any order.