Skip to content

Releases: GenericJam/mob_dev

0.5.13

30 May 20:39

Choose a tag to compare

Fixed

  • iOS deploy now ships the whole priv/, not just priv/repo/migrations + priv/static. MobDev.Release's iOS bundler copied only migrations and priv/static, so apps that bundle extra runtime assets under priv/:mix/:hex ebins for on-device Mix.install, or a vendored library's own priv/ (e.g. Livebook's priv/static + priv/livebook) — silently never reached the device. Now rsyncs all of priv/, matching the Android deployer. Unblocks on-device Mix.install and embedded Livebook on iOS. Verified on a physical iPhone: priv/mix/ebin (103 beams) and priv/livebook/static present on device, embedded Livebook serves, and Mix.install([{:short_uuid, "~> 0.1"}]) returns :ok.

0.5.12

29 May 22:58

Choose a tag to compare

Changed

  • OTP runtime bumped to 7d46fdd4 (Elixir 1.20.0-rc.5). @otp_hash now points at the otp-7d46fdd4 release: all four platform tarballs (ios-sim, ios-device, android, android-arm32) bundle Elixir 1.20.0-rc.5 matched to the OTP-29 erts. Completes the 1.19.5 to 1.20 runtime migration the bundled-versions manifest was already staged for. Verified end-to-end on a physical iPhone and a physical Android (Moto G): System.version 1.20.0-rc.5, OTP 29, Mix.install([{:short_uuid, "~> 0.1"}]) returns :ok with the dep compiled on-device.

Fixed

  • iOS {spawn, <linked-in driver>} now works (erts erts_open_driver). The iOS-build #ifdef __IOS__ guard returned BADARG for any open_port whose spawn_type included the EXECUTABLE bit (i.e. plain {spawn, Name}), firing before the linked-in-driver name lookup. This broke ram_file ({spawn, "ram_file_drv"}), and therefore file:open(_, [:ram]), erl_tar in-memory extract, hex_tarball.unpack, and Mix.install on iOS. The guard now fires only when no linked-in driver matched the name. Bundled in the 7d46fdd4 OTP tarballs.

0.5.11

20 May 17:39

Choose a tag to compare

Added

  • mob.exs :project_swift_sources config key — optional list of extra Swift sources to compile into the iOS app module alongside Mob's bridge sources. Threaded into both zig_build_binary_ios_sim and zig_build_binary_ios_device as -Dproject_swift_sources=<absolute,paths>. Comma-containing entries are rejected at the boundary; nil/[] is a no-op. Pairs with mob_new's project_swift_sources build hook (mob_new#5). Originally proposed by @dl-alexandre.

0.5.10

19 May 02:15

Choose a tag to compare

Added

  • mix mob.deploy --dist-port N and --node-suffix S flags — manual
    override path for the BEAM-distribution surface. When set, all targeted
    devices use the same value (use with --device <id> to be explicit).
    Nil falls back to per-device auto-allocation
    (Tunnel.dist_port(idx) + Discovery.Android.device_node_suffix /
    SIMULATOR_UDID-derived suffix). Resolves the
    register/listen error: no_reg_reply_from_epmd symptom seen when running
    multiple sims/emulators of the same app concurrently for cross-platform
    visual comparison.
  • MobDev.Device struct gains a :node_suffix field for plumbing the
    override per-device alongside :dist_port. Nil keeps auto-derive.
  • MobDev.Discovery.IOS.launch_app/3 accepts :node_suffix opt and
    forwards as SIMCTL_CHILD_MOB_NODE_SUFFIX to the launched sim. Companion
    to mob 0.6.10's MOB_NODE_SUFFIX support in mob_beam.m.
  • MobDev.Discovery.IOS.build_simctl_env/2 — pure helper extracted from
    launch_app/3 so override behaviour is unit-testable without spawning
    simctl. 7 new tests cover dist_port + node_suffix override paths.

Changed

  • MobDev.Connector.restart_app/1 pattern-matches :node_suffix from
    Device in both Android + iOS-sim variants, threading the value to the
    launchers.
  • MobDev.Deployer.deploy_all/1 accepts top-level :dist_port +
    :node_suffix opts; threaded through deploy_android and
    deploy_ios_simulator.

0.5.9

18 May 04:38

Choose a tag to compare

Changed

  • mix mob.enable tflite now injects {:nx_tflite_mob, "~> 0.0.3"}
    (Hex) instead of the GitHub-branch form. nx_tflite_mob v0.0.3 went
    live on Hex with 16 integration tests + a reproducible Mac host
    build path (see
    its CHANGELOG).
    Downstream Mob apps now get version-pinned deps + clean
    mix deps.tree output, instead of a transient github: checkout.

Notes

  • The Mac host-build path in nx_tflite_mob is for that package's own
    test suite, not for downstream consumers — production phone builds
    via mix mob.deploy --native continue to use the prebuilt Android
    AAR + iOS xcframework that mob_dev's MobDev.TfliteDownloader
    fetches.

0.5.8

17 May 23:07

Choose a tag to compare

Added

  • End-to-end mix mob.enable tflite — what 0.5.7 promised as
    "lands in 0.5.8". MobDev.NativeBuild now auto-detects the
    :nx_tflite_mob dep and threads the full TFLite path through
    Android + iOS sim + iOS device build pipelines:
    • maybe_build_tflite/1MobDev.TfliteDownloader.ensure/1 +
      MobDev.TfliteNif.build/2 for each target arch
    • tflite_zig_args_android/1 emits -Dtflite_static=true -Dtflite_lib=… for the per-ABI Android link
    • tflite_zig_args_ios/1 emits -Dtflite_static=true -Dtflite_dir=… -Dtflite_framework_dir=… for the iOS link
    • copy_tflite_runtime_lib_android/2 drops
      libtensorflowlite_jni.so into android/app/src/main/jniLibs/<abi>/
      during the assemble step
  • copy_tflite_frameworks_ios/3 (kept as future-compat hook) — see
    the iOS-deploy-fix gotcha below
  • 13 new tests covering the public NativeBuild plumbing
    (native_build_tflite_test.exs), bringing the TFLite suite to 76
    passing total

Fixed

  • iOS deploy: TFLite framework binaries are MH_OBJECT, not
    MH_DYLIB.
    TFLite's iOS xcframework slices ship their binaries as
    filetype=1 relocatable objects, which the linker statically pulls
    into the app's main Mach-O at build time. Trying to embed them as
    runtime .framework bundles tripped iOS install twice during this
    cut: first on missing per-framework Info.plist (which CocoaPods
    generates), then on "code signature version no longer supported"
    (iOS 26+ rejects v1 signatures, and codesign only makes v3 sigs
    for MH_EXECUTE/MH_DYLIB). The fix is to do nothing — the framework
    search-path arg already covers everything at build time.
  • Resolve :nx_tflite_mob via Mix.Project.deps_paths() rather
    than Path.join(deps_path, "nx_tflite_mob"). The latter assumes
    the dep landed in deps/ (hex / git deps do), but path: deps
    consume in-place from the user's source tree.

Verified on real hardware

  • Moto G Power 5G (BXM-8-256, Android 15): 75-117 ms YOLOv8n via
    NNAPI / mtk-gpu_shim
  • iPhone SE 3rd gen (A15, iOS 26.4): 24 ms YOLOv8n via Core ML → ANE
    (FP16 model; 214/385 nodes delegated)

0.5.7

17 May 22:47

Choose a tag to compare

Added

  • mix mob.enable tflite — wires TensorFlow Lite into a Mob project on
    iOS AND Android. Adds {:nx_tflite_mob, ...} to deps and generates
    <App>.TfliteInit (returns per-platform default delegate opts —
    NNAPI/mtk-gpu_shim on Android, Core ML delegate on iOS). The
    static-NIF table entry %{module: :tflite_nif, guard: "MOB_STATIC_TFLITE_NIF"}
    is registered in MobDev.StaticNifs.default_nifs/0, so the zig
    build picks it up automatically once tflite_static=true is set.
  • MobDev.TfliteDownloader — fetches tensorflow-lite-2.16.1.aar
    (Maven Central, Android) and TensorFlowLiteC-2.17.0.tar.gz
    (dl.google.com, iOS) into ~/.mob/cache/. Honours MOB_CACHE_DIR
    for test redirection and MOB_TFLITE_LOCAL_TARBALL_DIR for offline
    iteration.
  • MobDev.TfliteNif — cross-compiles tflite_nif.c (from the
    :nx_tflite_mob dep) per-arch and archives as libtflite_nif.a for
    static linking. Mirrors MobDev.NxEigenNif shape. Validates the
    produced symbol (tflite_nif_nif_init) before declaring success.

Bundle size impact: ~3-4 MB extracted (Android libtensorflowlite_jni.so),
~20-30 MB on iOS (TensorFlowLiteC + CoreML + Metal frameworks). Apps
that don't enable TFLite pay zero size cost — the guard keeps the
static-NIF table entry inactive.

End-to-end deploy (mob.deploy --native auto-build + runtime-lib
embedding) lands in 0.5.8; this release ships the building blocks.

0.5.6

16 May 22:28

Choose a tag to compare

Added

  • CLAUDE.md "Release flow" section pointing at the canonical process
    in mob/RELEASE.md
    (URL form so it resolves without a local mob checkout). mob_dev
    specifics: the pre-push hook additionally runs mix mob.security_scan
    here (this is the only repo that ships the scanner), and the OTP
    tarball workflow stays separate from mix.exs version bumps.
  • .githooks/pre-push — same script shipped in mob (cheap preflight
    always, release preflight when mix.exs changed). The
    mob.security_scan step is gated via mix help availability so the
    same hook script works in all three repos.

0.5.5

16 May 17:07

Choose a tag to compare

Fixed

  • Android 15 segfault on launch (Pixel 7+, after the OS rolled out via OTA). Bumps @otp_hash from 550d7b78d9045670 to pick up OTP tarballs cross-compiled with -Wl,-z,max-page-size=16384. Without the flag, every .so in the bundled OTP runtime (crypto.so, asn1rt_nif.so, dyntrace.so, etc.) shipped with 4KB-aligned ELF PT_LOAD segments. Android 15 enforces 16KB alignment on devices with 16KB-page kernels and refuses to load misaligned libs, crashing the app at startup. New tarballs are 16KB-aligned (Align=0x4000).

0.5.4

16 May 08:06

Choose a tag to compare

Fixed

  • HexDocs source links pointed at the non-existent main branch — corrected to master so each </> glyph in generated docs opens the actual source file.

Added

  • .github/workflows/test.yml — runs mix test, mix format --check-formatted, mix credo --strict, and mix mob.security_scan on push to master and on every PR.
  • .github/workflows/release.yml — on tag push, creates a GitHub Release whose body is the matching ## [X.Y.Z] section from this changelog.