[bug] iOS app crashes on devices when `tauri_plugin_nfc` is used
Description
On a brand new Tauri v2 project, when the official tauri_plugin_nfc is added to the project with pnpm tauri add nfc, and both Info.ios.plist and entitlements files are modified with the correct lines from the documentation, the app crashes when launched on a real device. On a simulator, the app launches correctly.
I also tried to add CoreNFC to the iOS Frameworks to bundle into the app (tauri.conf.json : bundle > iOS > frameworks), after reinitiating the iOS project with pnpm tauri ios init, it still crashes on launch.
Reproduction
- Create new Tauri v2 project with
pnpm create tauri-app testnfc --template svelte-ts --manager pnpm(I also tried with npm and vanilla JS, with the same result) cdin the project folder, install dependencies and runpnpm tauri ios init- Check that the app compiles on your device with
pnpm tauri ios dev. - Then, delete the
src-tauri/gen/applefolder, runpnpm tauri ios initagain, and runpnpm tauri add nfc - Finally, add required lines from the documentation in both Info.ios.plist and entitlements files, and run
pnpm tauri ios devagain.
The app crashes on launch on your device. I tested with either an iPhone 12 or an iPad 2017.
pnpm tauri info output
[✔] Environment
- OS: Mac OS 14.7.0 arm64 (X64)
✔ Xcode Command Line Tools: installed
✔ rustc: 1.80.1 (3f5fd8dd4 2024-08-06)
✔ cargo: 1.80.1 (376290515 2024-07-16)
✔ rustup: 1.27.1 (2024-04-24)
✔ Rust toolchain: stable-aarch64-apple-darwin (default)
- node: 20.14.0
- pnpm: 9.7.0
- yarn: 1.22.22
- npm: 10.7.0
[-] Packages
- tauri 🦀: 2.0.1
- tauri-build 🦀: 2.0.1
- wry 🦀: 0.44.1
- tao 🦀: 0.30.2
- tauri-cli 🦀: 2.0.1
- @tauri-apps/api : 2.0.1
- @tauri-apps/cli : 2.0.0
[-] Plugins
- tauri-plugin-shell 🦀: 2.0.0
- @tauri-apps/plugin-shell : 2.0.0
- tauri-plugin-nfc 🦀: 2.0.0
- @tauri-apps/plugin-nfc : 2.0.0
[-] App
- build-type: bundle
- CSP: unset
- frontendDist: ../build
- devUrl: http://localhost:1420/
- framework: Svelte
- bundler: Vite
[-] iOS
- Developer Teams: ######
2.0.1/2.0.2 didn't fix the issue 😞
Hello !
Thank you again for your great work. Do you have any news on that issue ?
Thanks
Hello @FabianLars ,
Planet-nine-app managed to find a workaround to this issue. Apparently it was related to the different linking for CoreNFC, creating a new nfc.swift file from Xcode with import CoreNFC solved this. More details here.
I'm not sure if this should be an extra step in Tauri's docs or whether a bugfix during Tauri build process on iOS.
Thank you again for your awesome work !
This is indeed a great fix. Additional info: the file by itself is not enough (if manually created in cli), you have to add it to the project with Xcode, and it will generate a Bridging-Header file. Then it will work
I currently can't test this myself so i'd appreciate if someone of you could test something for me. In your Cargo.toml file change the nfc plugin to pull it from git:
tauri-plugin-nfc = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "fix/nfc-xcode-project" }
Remember to remove the workaround from the other comments for the test.
I followed the exact test protocol I wrote in this issue's description and it didn't work out, I got the same crash I used to have on real devices. For the record, my test device is an old 2017 iPad without NFC, but it shouldn't be a problem to launch the app even if a capability is not supported by a device. For instance it did launch with the above workaround.
Here's the log from my terminal after pnpm tauri ios dev :
Symbol Path: /Users/itess/Library/Developer/Xcode/iOS DeviceSupport/iPad6,11 16.7.11 (20H360)/Symbols
[100%] Connecting to remote debug server
-------------------------
(lldb) command source -s 0 '/tmp/A1FC7EE5-FF3E-40FE-AD27-63C32202D329/fruitstrap-lldb-prep-cmds-7097924e5579e2efacd9f7925813cd32038be22f'
Executing commands in '/tmp/A1FC7EE5-FF3E-40FE-AD27-63C32202D329/fruitstrap-lldb-prep-cmds-7097924e5579e2efacd9f7925813cd32038be22f'.
(lldb) platform select remote-'ios' --sysroot '/Users/itess/Library/Developer/Xcode/iOS DeviceSupport/iPad6,11 16.7.11 (20H360)/Symbols'
Platform: remote-ios
Connected: no
Sysroot: /Users/itess/Library/Developer/Xcode/iOS DeviceSupport/iPad6,11 16.7.11 (20H360)/Symbols
SDK Path: "/Users/itess/Library/Developer/Xcode/iOS DeviceSupport/iPad6,11 16.7.11 (20H360)/Symbols"
(lldb) target create "/Users/itess/Documents/Repos/testnfcfix/src-tauri/gen/apple/build/Payload/testnfcfix.app"
Current executable set to '/Users/itess/Documents/Repos/testnfcfix/src-tauri/gen/apple/build/Payload/testnfcfix.app' (arm64).
(lldb) script fruitstrap_device_app="/private/var/containers/Bundle/Application/15C704F8-406A-4E3F-9F4A-C92F314253DB/testnfcfix.app"
(lldb) script fruitstrap_connect_url="connect://127.0.0.1:49906"
(lldb) script fruitstrap_output_path=""
(lldb) script fruitstrap_error_path=""
(lldb) target modules search-paths add /usr "/Users/itess/Library/Developer/Xcode/iOS DeviceSupport/iPad6,11 16.7.11 (20H360)/Symbols/usr" /System "/Users/itess/Library/Developer/Xcode/iOS DeviceSupport/iPad6,11 16.7.11 (20H360)/Symbols/System" "/private/var/containers/Bundle/Application/15C704F8-406A-4E3F-9F4A-C92F314253DB" "/Users/itess/Documents/Repos/testnfcfix/src-tauri/gen/apple/build/Payload" "/var/containers/Bundle/Application/15C704F8-406A-4E3F-9F4A-C92F314253DB" "/Users/itess/Documents/Repos/testnfcfix/src-tauri/gen/apple/build/Payload" /Developer "/Users/itess/Library/Developer/Xcode/iOS DeviceSupport/iPad6,11 16.7.11 (20H360)/Symbols/Developer"
(lldb) command script import "/tmp/A1FC7EE5-FF3E-40FE-AD27-63C32202D329/fruitstrap_7097924e5579e2efacd9f7925813cd32038be22f.py"
(lldb) command script add -f fruitstrap_7097924e5579e2efacd9f7925813cd32038be22f.connect_command connect
(lldb) command script add -s asynchronous -f fruitstrap_7097924e5579e2efacd9f7925813cd32038be22f.run_command run
(lldb) command script add -s asynchronous -f fruitstrap_7097924e5579e2efacd9f7925813cd32038be22f.autoexit_command autoexit
(lldb) command script add -s asynchronous -f fruitstrap_7097924e5579e2efacd9f7925813cd32038be22f.safequit_command safequit
(lldb) connect
(lldb) run
success
(lldb) safequit
Application has not been launched
Failed to deploy app to device: command ["ios-deploy", "--debug", "--id", "7097924e5579e2efacd9f7925813cd32038be22f", "--no-wifi"] exited with code 1
Error Failed to deploy app to device: command ["ios-deploy", "--debug", "--id", "7097924e5579e2efacd9f7925813cd32038be22f", "--no-wifi"] exited with code 1
I'm not sure this log can help you, is there any way I can provide you more context ?
hmm sad, but expected. i just saw this option mentioned somewhere else and thought it's worth a try. thanks for testing.
I'm not sure this log can help you, is there any way I can provide you more context ?
i'm too unfamiliar with ios for any further investigation at the moment tbh. i'll try to make some time to at least try to reproduce this on my end (back when we created the app it worked fine on my devices and it doesn't seem to be affecting every project either).
this is the crash:
dyld[614]: Library not loaded: @rpath/libswiftCoreNFC.dylib
Referenced from: <C12551F0-684D-3700-9CDE-18B0E7B18D3A> /private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/testnfc.debug.dylib
Reason: tried: '/usr/lib/system/introspection/libswiftCoreNFC.dylib' (no such file, not in dyld cache), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/Frameworks/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/Frameworks/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/Frameworks/libswiftCoreNFC.dylib' (no such file)
Library not loaded: @rpath/libswiftCoreNFC.dylib
Referenced from: <C12551F0-684D-3700-9CDE-18B0E7B18D3A> /private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/testnfc.debug.dylib
Reason: tried: '/usr/lib/system/introspection/libswiftCoreNFC.dylib' (no such file, not in dyld cache), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/Frameworks/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/Frameworks/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/Frameworks/libswiftCoreNFC.dylib' (no such file)
dyld config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/usr/lib/libLogRedirect.dylib:/usr/lib/libBacktraceRecording.dylib:/usr/lib/libMainThreadChecker.dylib:/usr/lib/libRPAC.dylib:/System/Library/PrivateFrameworks/GPUToolsCapture.framework/GPUToolsCapture:/usr/lib/libViewDebuggerSupport.dylib
Library not loaded: @rpath/libswiftCoreNFC.dylib
Referenced from: <C12551F0-684D-3700-9CDE-18B0E7B18D3A> /private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/testnfc.debug.dylib
Reason: tried: '/usr/lib/system/introspection/libswiftCoreNFC.dylib' (no such file, not in dyld cache), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/Frameworks/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/Frameworks/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/libswiftCoreNFC.dylib' (no such file), '/private/var/containers/Bundle/Application/180D3671-0098-4585-82B4-09E3BA21DD2B/testnfc.app/Frameworks/libswiftCoreNFC.dylib' (no such file)
dyld config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/usr/lib/libLogRedirect.dylib:/usr/lib/libBacktraceRecording.dylib:/usr/lib/libMainThreadChecker.dylib:/usr/lib/libRPAC.dylib:/System/Library/PrivateFrameworks/GPUToolsCapture.framework/GPUToolsCapture:/usr/lib/libViewDebuggerSupport.dylib
it seems like the easy fix is bumping the target iOS version to 14+:
If you set your deployment target to iOS 14.0 or higher, the libswiftCoreNFC.dylib problem usually disappears because Xcode assumes the library is present in the OS for all devices you target. If you keep the target at 13.x or below, you need to embed the Swift NFC runtime manually.
now we just need to figure out how to embed that runtime :| seems tricky, we'll probably need to keep a copy on the cli
To me setting the minimal target iOS version to 14 or 15 (for all tauri apps) seems easier since it will not exclude any other device than the version 13 did (see https://iosref.com/ios). I didn't test this fix however
To me setting the minimal target iOS version to 14 or 15 (for all tauri apps) seems easier since it will not exclude any other device than the version 13 did (see https://iosref.com/ios). I didn't test this fix however
that's what i was thinking too... doesn't seem like there's a way to embed the dylib, seems like the alternative would be using objc to use the NFC (I'm not even sure if that would work, I doubt tbh). so maybe we just document that the target iOS should be increased for the NFC plugin
OK ! I was thinking about documentation + iOS 15 as a minimal target version when the ios project is created with tauri ios init, but documentation only seems fine