Having x8664 code is not sufficient to distinguish if a binary is intended for the iOS Simulator, a macOS app, or a Mac Catalyst app. Combing built binaries across different destinations (which includes the simulator vs. Device binaries) is not a supported combination - there is no Apple platform where ARM code and x8664 code in the same binary is a correct configuration. VICE is an emulator collection which emulates the CBM-II (aka C610), the PLUS4, practically all PET models, the VIC20, the C128, the C64-DTV, and the C64. It is running on the MAC OS X, GP2X, Amiga, QNX 6.x, BeOS, Acorn RISC OS, OS/2, Windows 32-Bit, MS-DOS or the Unix. It is the cross-platform & the free emulator for Commodore’s 8-Bit PC. Android Device & Emulator. If it's not installed, please open the iOS Simulator Setup. $ open /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app Open in the folder. You can also do this manually. You can open the folder and start the simulator by clicking on it.
Installing dependencies#
You will need Node, Watchman, the React Native command line interface, Xcode and CocoaPods.
While you can use any editor of your choice to develop your app, you will need to install Xcode in order to set up the necessary tooling to build your React Native app for iOS.
Node & Watchman#
We recommend installing Node and Watchman using Homebrew. Run the following commands in a Terminal after installing Homebrew:
If you have already installed Node on your system, make sure it is Node 12 or newer.
Watchman is a tool by Facebook for watching changes in the filesystem. It is highly recommended you install it for better performance.
Xcode#
The easiest way to install Xcode is via the Mac App Store. Installing Xcode will also install the iOS Simulator and all the necessary tools to build your iOS app.
If you have already installed Xcode on your system, make sure it is version 10 or newer.
Command Line Tools#
You will also need to install the Xcode Command Line Tools. Open Xcode, then choose 'Preferences...' from the Xcode menu. Go to the Locations panel and install the tools by selecting the most recent version in the Command Line Tools dropdown.
Installing an iOS Simulator in Xcode#
To install a simulator, open Xcode > Preferences... and select the Components tab. Select a simulator with the corresponding version of iOS you wish to use.
CocoaPods#
CocoaPods is built with Ruby and it will be installable with the default Ruby available on macOS. You can use a Ruby Version manager, however we recommend that you use the standard Ruby available on macOS unless you know what you're doing.
Using the default Ruby install will require you to use sudo
when installing gems. (This is only an issue for the duration of the gem installation, though.)
For more information, please visit CocoaPods Getting Started guide.
React Native Command Line Interface#
React Native has a built-in command line interface. Rather than install and manage a specific version of the CLI globally, we recommend you access the current version at runtime using npx
, which ships with Node.js. With npx react-native <command>
, the current stable version of the CLI will be downloaded and executed at the time the command is run.
Creating a new application#
If you previously installed a global react-native-cli
package, please remove it as it may cause unexpected issues.
You can use React Native's built-in command line interface to generate a new project. Let's create a new React Native project called 'AwesomeProject':
This is not necessary if you are integrating React Native into an existing application, if you 'ejected' from Expo, or if you're adding iOS support to an existing React Native project (see Integration with Existing Apps). You can also use a third-party CLI to init your React Native app, such as Ignite CLI.
[Optional] Using a specific version or template#
If you want to start a new project with a specific React Native version, you can use the --version
argument:
You can also start a project with a custom React Native template, like TypeScript, with --template
argument:
Note If the above command is failing, you may have old version of react-native
or react-native-cli
installed globally on your pc. Try uninstalling the cli and run the cli using npx
.
Running your React Native application#
Step 1: Start Metro#
First, you will need to start Metro, the JavaScript bundler that ships with React Native. Metro 'takes in an entry file and various options, and returns a single JavaScript file that includes all your code and its dependencies.'—Metro Docs
To start Metro, run npx react-native start
inside your React Native project folder:
react-native start
starts Metro Bundler.
If you use the Yarn package manager, you can use yarn
instead of npx
when running React Native commands inside an existing project.
If you're familiar with web development, Metro is a lot like webpack—for React Native apps. Unlike Kotlin or Java, JavaScript isn't compiled—and neither is React Native. Bundling isn't the same as compiling, but it can help improve startup performance and translate some platform-specific JavaScript into more widely supported JavaScript.
Step 2: Start your application#
Let Metro Bundler run in its own terminal. Open a new terminal inside your React Native project folder. Run the following:
Macos Ios Simulator Download
You should see your new app running in the iOS Simulator shortly.
npx react-native run-ios
is one way to run your app. You can also run it directly from within Xcode.
If you can't get this to work, see the Troubleshooting page.
Running on a device#
The above command will automatically run your app on the iOS Simulator by default. If you want to run the app on an actual physical iOS device, please follow the instructions here.
Modifying your app#
Now that you have successfully run the app, let's modify it.
- Open
App.js
in your text editor of choice and edit some lines. - Hit
⌘R
in your iOS Simulator to reload the app and see your changes!
That's it!#
Congratulations! You've successfully run and modified your first React Native app.
Now what?#
- If you want to add this new React Native code to an existing application, check out the Integration guide.
If you're curious to learn more about React Native, check out the Introduction to React Native.

Bringing iOS Apps to macOS Using Marzipanify
March 01 2019At WWDC 2018 Apple gave us a ‘sneak peek’ at perhaps one of the most impactful developments on macOS since the transition to Mac OS X: UIKit apps running on the desktop. Today, I'm going to detail a special tool I built, called marzipanify, to get started with UIKit on the Mac early, and start the initial bringup of your iOS app on macOS.
💡 Don't miss the other posts in this series
Part one: Bringing iOS Apps to macOS Using Marzipanify
Part two: Making Marzipan Apps Sing
Part three: Deeper Integration with Marzipan
Overview
UIKit on the desktop is not like traditional macOS frameworks; it has its own /System/iOSSupport
directory that houses a web of dependencies taken from the iOS Simulator — iOS variants of WebKit, MapKit, and more — and is compiled as if it were a whole other platform to macOS, called 'iOSMac'. We know iOSMac by another name, rumored since December of 2017: Marzipan.
How it works
There's another reason for the iosmac distinction: many of the frameworks underneath, née iOS Simulator, clash horrendously with the built-in macOS frameworks, thanks to a decade of divergence from OS X. Both iOS and macOS today share a UIFoundation framework to help support UIKit and AppKit and provide common code, but UIFoundation makes decisions at runtime based on which platform it's running on that affect everything from Interface Builder to text rendering. At its simplest level, this means that if you link AppKit into your iOSMac app, all manner of things will explode in your app. The iosmac
linker variant for iOSMac binaries explicitly prevents loading non-iosmac binaries and libraries into your code (unless they're whitelisted).
macOS has several new components to support UIKit apps. At the top level is your UIKit app, except it doesn't run directly. Its layers are hosted in another process, UIKitHostApp.xpc
, which provides the AppKit-based window chrome and bridge to Mac features like the menu bar and toolbar. Each UIKitHostApp is managed by a singular UIKitSystem
app, which acts as the window/process/event manager. UIKitSystem takes the place in which SpringBoard traditionally sits on iOS, acting as the shell UI for all iOSMac apps, but bridging management to macOS' own WindowServer instead of providing a homescreen of its own.
Altogether, it appears running modern UIKit on macOS is so much more complex than the more-obvious tack Chameleon took when it rewrote UIKit for the Mac all those years ago. It's not a virtual machine by any stretch, despite evolving from the iOS Simulator, but it certainly goes to great lengths to distance itself from how Mac apps traditionally work. Perhaps that is a function of its incomplete state, or perhaps it hints at a vision for a new baseline for all Mac apps.
So. Enough preamble. How do I build my own UIKit apps on macOS?
Security & Preparation
iOSMac apps follow the modern pattern with Apple technologies in that they are 'entitlement-gated'. This means that unless your app is signed with private entitlements from Apple, the system will refuse to launch it. Because of this, even developers hoping to experiment with building iOSMac apps early, to get a head-start on macOS 10.15's public API, are unable to build and run their code by default on macOS.
Fortunately, macOS, unlike iOS, has a system which allows you to completely disable security and bypass everything. While that sounds terrifying, don't forget that that's just how macOS worked by default a few OS releases ago. It's only in recent years that everything has been locked down tightly.
To disable security, you first need to disable System Integrity Protection from Recovery Mode, and then you add a boot argument to bypass Apple Mobile File Integrity. Once disabled, this is how your Mac will run by default. If you wish to re-enable it, you can do so in the same way.
In Recovery Mode, use Terminal:
Now you can reboot into macOS proper.
Getting up and running
At this point, you could absolutely set up a build environment for iOSMac apps, but it's an arduous and complex process.
In some form or other, you need to:
- Copy all the UIKit headers to the Mac version of UIKit
- Port the UIKit tbd (linker symbols definition file) to the Mac framework
- Set up a project in Xcode that links to the Mac version of UIKit in
/System/iOSSupport/PrivateFrameworks/UIKitCore.framework
- Create a custom linker script that passes the correct arguments to build an iosmac binary instead of a macosx binary
- (and probably a lot more)
My recommendation is simple: do not even think about it. Why? Because I have built a much, much better and safer way…
When learning about iOSMac and its similarity with the iOS Simulator, I had a hunch one would be able to make an iOS Simulator app run as an iOSMac app. I studied the built-in iOSMac apps on Mojave intently, and, from what I knew about the Mach-O binary format, I was pretty sure that I could perform the requisite changes statically on an existing binary. Enter marzipanify.
marzipanify
marzipanify is a tool I created to statically convert an iOS app built for the iOS Simulator to macOS. It means you can continue working on and building your existing iOS app from its existing project, using the existing iOS SDK, and just run the tool against the Simulator build to create a functioning Mac app. As a bonus, marzipanify will yell at you when you're linking against a framework or library that doesn't currently exist in the iOSMac runtime. It trivializes the process so you can focus on adapting your app rather than managing a build environment.
How does marzipanify work?
marzipanify does five important things:
- it repackages your iOS app in a format macOS will be happy with
- it redirects all your framework links to their places in the iOSMac runtime
- it rewrites the mach header of your binaries to change the flag that determines whether they are macosx or iosmac binaries
- it updates your
Info.plist
with the appropriate keys for iosmac apps - it re-signs your app with the private entitlement all iosmac apps require
It performs these steps recursively on your binary and its embedded frameworks.
Everything marzipanify does can be done by hand, too. Repackaging is just a lot of moving files around and creating the correct folder structure, redirecting libraries can be done with install_name_tool
, and modifying the mach header can be done with a disassembler and hex editor. Indeed, that is the process by which I gradually figured out the steps in the first place. If you look at the source code, much of marzipanify is calling out to other commandline tools to do the hard work.
Using marzipanify
The easy way, if your app and its dependencies target iOS 12.0 as the minimum OS:
The more likely way, if your app needs to target an older iOS:
If your app has everything it needs included in the iOSMac runtime in Mojave, you should now have an app you can double-click and run.
Whoa whoa whoa, back up a bit. INJECT_MARZIPAN_GLUE? Explain.
In iOS 12, Apple updated the default output of the Xcode linker to use a new load command called LC_BUILD_VERSION instead of the traditional LC_VERSION_MIN_IPHONEOS and LC_VERSION_MIN_MACOSX, to prep for an environment where a single binary can run on both iOS and macOS. All the iOSMac apps included in Mojave use this method, and it's what the system expects for all iOSMac apps. The catch is that apps targeting an OS before iOS 12 use the other load command, and it's not trivial to add a whole new load command to an existing binary.
Mac Iphone Simulator Clear Cache
To solve this problem in a simplistic way, marzipanify has a mode where it builds a library and injects it into your app at conversion time. This library uses interposing to trick dyld, the linker, into thinking the app is running as an iosmac binary even when it's still a macosx binary. It works! It's a hack! But clearly, there be dragons.
Tune-up
Depending on how complex your app is, at this point you could be looking at a CrashReporter window and scratching your head. The thing is, not every iOS framework exists in iOSMac yet. In fact, other than WebKit, MapKit and AVFoundation, you don't have a lot to work with in this first iteration of iOSMac. Even if all the frameworks neccessary for your app are there, you might be using a number of classes that are omitted or deprecated, like UIFeedbackGenerator, UIWebView, or MFComposeViewController. At this stage, your only option is to start #ifdef
ing out portions of your codebase.
With enough of your app's non-essential features disabled, with any luck you should be greeted by something onscreen, and with a little cleanup you may just have a working app. Louis D'hauwe's Pixure (sadly no longer available) is one such success. James Thomson was also able to port the iOS version of PCalc to macOS with marzipanify, much like Peter Steinberger did for PSPDFKit's viewer app.
Mac Ios Simulator Black Screen
Advanced Functionality
One very interesting benefit of how 'INJECT_MARZIPAN_GLUE' works in marzipanify is that you can customize the source code you want to inject into the target app. How is this useful? Well, it allows you to patch apps that you may not have the source code to. In fact, I used this mechanism to 'port' Apple's own Contacts app to macOS. While this probably isn't something you need to know about in your own work, personally I like to keep a separation between the crazy hacks and patches I might need for bringup of a particular app, and its clean, shipping iOS project.
Online Ios Simulator
Make it sing
Emulate Iphone On Mac
When Apple announced UIKit on the Mac, they mentioned a list of features to make a UIKit app feel more at home on the desktop, with menus and toolbars, mouse events and more. However, you may have realized that these classes are not included in the iOS SDK, and thus can't be used in your iOS Simulator build. I will detail how you can use the new Mac-specific classes to make your app look much more like a Mac app in a future post.
Conclusion
For now, I hope I've given you a superficial overview of what marzipanify is and what it can do: it's a very simple tool to kickstart your UIKit app bringup on macOS months before the SDK becomes public. It's certainly not all you need to make a great UIKit Mac app, but it's enough to get you started and thinking about the changes and redesigns you might need to make to your app and its layout to prepare it for a future on the Mac.
There's a bright future for UIKit on the Mac, and I genuinely believe that the quick & dirty ports that we've seen so far (even from Apple) are only scratching the surface of what's possible. But for now, developers gotta develop, so onwards with your quick & dirty ports and start experimenting. As always, you can find me at @stroughtonsmith.