Repository navigation
feat(ios): run iOS apps on an Apple silicon Mac with --device mac - #6205
Draft
NathanWalker wants to merge 1 commit into
Draft
NathanWalker wants to merge 1 commit into
NathanWalker wants to merge 1 commit into
Conversation
Apple silicon Macs run iPhone and iPad apps as "Designed for iPad". @nativescript/ios supports this from NativeScript/ios#551, which loads UIKit and the other iOS-only frameworks from /System/iOSSupport. The Mac is offered as an iOS device ("My Mac (Designed for iPad)"). It is listed by `ns devices` and used only when `--device` is `mac` or the Mac's provisioning UDID, so a plain `ns run ios` never launches on it. - Build: the signed iphoneos build with destination `platform=macOS,arch=arm64,variant=Designed for iPad,id=<UDID>`, into platforms/ios/build/mac so it doesn't replace device or simulator output. - Install: the bundle goes into the wrapper layout macOS requires (<Name>.app/Wrapper/<Name>.app plus a WrappedBundle symlink), then `open -n` launches it. - Sync, logs (`log stream`) and the debugger (Darwin notification, then a local socket) work on the local file system, the same way they do for a simulator. - Warns when @nativescript/ios is older than NativeScript/ios#551.
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
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. |
This branch has not been deployed
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 free
to 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.
PR Checklist
What is the current behavior?
Since NativeScript/ios#551, an iOS app can run on an Apple silicon Mac as "Designed for iPad": it loads UIKit and the other iOS-only frameworks from
/System/iOSSupport. The CLI has no way to target the Mac, so today you build withxcodebuild, build the wrapper bundle and launch it by hand.What is the new behavior?
The Mac is an iOS device, not a new platform, so
run,debug,deployanddeviceswork with no new commands. It is listed byns devices, butns run iosonly uses it when--deviceismacor the Mac's provisioning UDID. People with a phone plugged in won't get a Mac launch as well.This is a different product from #6125 (
ns run catalyst). Catalyst rebuilds the app against the macOS SDK. This runs the unmodified iOS (iphoneos) build, the same binary that ships to devices. The two don't overlap and can land independently.How it works
Discovery (
IOSMacDeviceDiscovery):sysctl hw.optional.arm64because Rosetta hides it fromprocess.arch.--emulator.system_profiler SPHardwareDataType.Build:
iphoneosbuild with-destination 'platform=macOS,arch=arm64,variant=Designed for iPad,id=<UDID>'and-allowProvisioningDeviceRegistration, so the profile includes this Mac.platforms/ios/build/mac, so it doesn't replace device or simulator builds.buildForMacflag onIBuildData/IBuildForDevice, set next to eachbuildForDevice.Install and launch (
IOSMacApplicationManager):<Name>.app/Wrapper/<Name>.appplus aWrappedBundlesymlink.open -n <wrapper>.pgrep. macOS runs a copy of the wrapper from/private/var/folders, not from the install path.Sync: local file copies, like a simulator.
IOSMacDevice.isEmulatoristrueso it uses those code paths.Logs:
log stream --predicate 'process == "<exe>" AND <IOS_LOG_PREDICATE>'.Debugger:
notifyutil -p <appId>:NativeScript.Debug.AttachRequest.127.0.0.1.Runtime check: warns when
@nativescript/iospredates fix(runtime): load iOS system frameworks from /System/iOSSupport on a Mac ios#551:nextbuilds before9.1.0-next.2026-11-11-43080423883Older runtimes stop at launch on a Mac.
Tested locally
M3 Max, macOS 26.6.2, Xcode 27, with an Angular + Vite app on
@nativescript/ios@next:ns devices ioslists the Mac--device macselects it; plainns run iosdoesn'tbuild/mac, provisioning includes the Mac (about 20 s)open -nlaunchlog stream--no-hmrsync + restart,ns debugKnown issue: syncing breaks the code signature
The CLI syncs app files (and
.nsbuildinfo) into the signed bundle. That invalidates its seal:codesign --verify --strictreports "a sealed resource is missing or invalid". macOS then refuses to launch the app and shows the "damaged, move to Trash" dialog.Re-signing the inner bundle with the identity it was built with fixes it. It takes about 0.1 s and keeps the entitlements:
Proposed fix:
open, runcodesign --verify --strict, which takes about 0.04 s.Vite HMR modules come from the dev server and are never written into the bundle, so HMR edits shouldn't trigger this.
Open questions
--device macunderios, as here, or a--macflag, or a separate platform? A device seemed the least new surface.isEmulator = truefor a Mac: the simulator's local-file code paths are exactly right, but the name is misleading. Add anisLocal/runsOnHostcapability instead? That means auditing everyisEmulatorcheck.file:runtimes can't be version-checked, so this warns.--device macon one give an explicit error?