Skip to main content
Tutorials

Cordova and Ionic iOS builds on Windows, with iPhone debugging

This tutorial walks you through building a Cordova or Ionic project into an iOS app on Windows, debugging it on an iPhone, and building an .ipa you can upload to App Store Connect. It’s for developers who build apps with web technologies and don’t have a Mac. You need an Apple Developer account, an iPhone and a USB cable, and you need to have installed KXBuild.

Why cordova build ios doesn’t work on Windows

cordova platform add ios runs on Windows and generates an Xcode project under platforms\ios. But cordova build ios and cordova run ios call Xcode’s build tools, so they only run on macOS.

With KXBuild, KXBuild builds, installs and debugs the iOS app, and every other cordova command works as usual. cordova create, cordova plugin add and cordova prepare are unaffected, and the Android app still builds with cordova build android.

Create a Cordova project and add the iOS platform

For an existing project, add the iOS platform in the project folder, then open the platforms\ios folder in VS Code with File > Open Folder…. Otherwise, install Cordova with npm, create a project, cd into the project folder, then add the iOS platform. platform add fails if you run it outside the project folder.

1npm install -g cordova
2cd D:\work
3cordova create MyApp com.example.myapp MyApp
4cd MyApp
5cordova platform add ios

The second argument to cordova create is the bundle ID and the third is the app name. Change the bundle ID to your own reverse domain, and use the same value when you register the App ID in your Apple Developer account.

Current versions of cordova-ios always name the project App, so platforms\ios contains App.xcodeproj and App.xcworkspace. Always build App.xcworkspace. Dependencies are managed with Swift packages by default, so you don’t need CocoaPods.

Using Ionic

New Ionic projects use Capacitor by default. To use Cordova, add –cordova to ionic start. Install the Ionic CLI and Cordova first, then create the project.

1npm install -g @ionic/cli cordova
2cd D:\work
3ionic start myApp tabs --type=angular --cordova --package-id=com.example.myapp
4cd myApp
5ionic cordova platform add ios

From then on, replace each cordova command in this tutorial with its ionic cordova equivalent, for example ionic cordova prepare ios instead of cordova prepare ios. The difference is that ionic cordova prepare runs an Ionic build first, compiling your web code into www, then syncs it to platforms\ios. For an existing Ionic Cordova project, run ionic cordova platform add ios in the project folder.

Set up iOS in config.xml

Cordova generates and updates the iOS project from config.xml. Change the bundle ID, version and permission descriptions here, and each prepare writes them to platforms\ios. If you edit the same settings directly in platforms\ios, the next prepare may overwrite them.

 1<widget id="com.example.myapp" version="1.0.0" ios-CFBundleVersion="1"
 2        xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
 3    <name>MyApp</name>
 4    <platform name="ios">
 5        <preference name="deployment-target" value="13.0" />
 6        <edit-config target="NSCameraUsageDescription" file="*-Info.plist" mode="merge">
 7            <string>Used to take your profile photo</string>
 8        </edit-config>
 9    </platform>
10</widget>

Here’s what each setting does.

Setting What it does
id Bundle ID. Must match the App ID registered in your developer account and the provisioning profile
version Version shown on the App Store
ios-CFBundleVersion Build number. Each upload to App Store Connect needs a higher one than the last
name App name, also used as the .ipa file name
deployment-target Minimum supported iOS version
edit-config Writes keys into Info.plist. Permission descriptions go here

Apps that use the camera, photo library, location or microphone must include the matching permission description. Without it, the app crashes as soon as it calls the API, and App Review rejects it. After editing config.xml, run cordova prepare ios.

Put the signing certificate and provisioning profile in the keychain folder. During development, use an Apple Development certificate and a Development provisioning profile that includes this iPhone. See Certificates and signing.

Add plugins

Add plugins with cordova plugin add as usual, for example the camera plugin.

1cordova plugin add cordova-plugin-camera

Most plugins are added to the project as Swift packages or source files and build right away. When a plugin has CocoaPods dependencies, a Podfile appears in platforms\ios. Cordova doesn’t install those pods on Windows, so run pod install once in platforms\ios, and again every time you add or remove such a plugin.

1cd platforms\ios
2pod install

For more, see Develop iOS apps with CocoaPods on Windows.

Run doctor

After adding the platform and plugins, run doctor once. It checks your build environment and prepares the iOS project. Use either of these.

  • VS Code extension. In the title bar of the KXBuild view, open the ··· menu and run Doctor (fix environment).
  • Command line. Run the command below in the Cordova project folder.
1kxbuild doctor .\platforms\ios\App.xcworkspace

Run on your iPhone

Open the platforms\ios folder in VS Code, and the KXBuild view lists the App project. Connect the iPhone with a cable. The first time, you need to install the Apple device drivers, tap Trust This Computer on the phone and turn on Developer Mode. See Set up your device. Then click the iPhone under the device node in the KXBuild view to make it the active device, and press F5.

KXBuild builds, signs, installs and launches the app, then attaches the debugger. The first time you debug on a given iOS version, KXBuild downloads its device symbols. It’s several GB, but only once, and progress shows in a notification.

Sync web code changes

Write your web code in the www folder of the project root. After changes, run cordova prepare ios to sync www, config.xml and plugin changes to platforms\ios, then stop debugging and press F5 again.

1cd D:\work\MyApp
2cordova prepare ios

Don’t edit files in platforms\ios\www directly, since the next prepare overwrites them. The Restart button on the debug toolbar doesn’t rebuild, so use F5 after syncing.

Debug web and native code

A Cordova app contains two kinds of code, and each has its own way to debug.

  • Native code. Set breakpoints in VS Code in plugins’ Objective-C and Swift sources and in native code under the App folder. They work as soon as you press F5, with the standard Variables, Call Stack and Debug Console views. See Run and debug.
  • Web code. Get your page logic working first with the developer tools in a desktop browser, since it behaves much the same as on the phone. For problems that only happen on the iPhone, temporarily add an in-page debug panel such as vConsole or Eruda to the Debug build to see console output, errors and network requests on the phone, and remove it before release. If you have a Mac at hand, you can also connect Safari’s Web Inspector to the WebView in a Debug build.

When a call into a native plugin misbehaves, set a breakpoint in the plugin’s native method and call it once from JS to see the arguments passed to native code and the return value. The app’s native logs and crash information are in Output > KXBuild Console, and the build log is in Output > KXBuild.

Build a Release .ipa

Before submitting, change version and ios-CFBundleVersion in config.xml and run cordova prepare ios. The keychain folder needs an Apple Distribution certificate and an App Store provisioning profile. Use either of these.

  • VS Code extension. Switch the configuration to Release in the Build configuration node of the KXBuild view, then run KXBuild: Build from the Command Palette.
  • Command line. Run the command below in the Cordova project folder.
1kxbuild build .\platforms\ios\App.xcworkspace -c Release

If the project’s Release configuration doesn’t specify a distribution certificate, add -D CODE_SIGN_IDENTITY="Apple Distribution" on the command line to override it for that build.

When the build finishes, you get platforms\ios\build\MyApp.ipa, named after name in config.xml. Upload it to App Store Connect with Appuploader on Windows, and when processing finishes, install it from TestFlight to check it on your iPhone before submitting it for review. See Release and App Store submission. App Review is strict with apps that only wrap a website and offer nothing app-specific, so before submitting, make sure your app uses native capabilities or offers an experience a website can’t.

FAQ

cordova platform add ios says it can’t find a project

You’re not in the Cordova project folder. cd into the folder cordova create generated (the one containing config.xml), then run platform add.

Changes to web code or config.xml don’t show up on the phone

You didn’t run cordova prepare ios, or didn’t press F5 again afterward. For Ionic projects, use ionic cordova prepare ios, which recompiles your web code first.

The build can’t find a plugin’s header or module

The plugin has CocoaPods dependencies, but pod install wasn’t run in platforms\ios. Run it, then build App.xcworkspace again.

The app crashes when it opens the camera or photo library

Info.plist is missing the permission description. Add an edit-config to config.xml as shown above, run cordova prepare ios, then press F5 again.

For other errors, see Troubleshooting. For signing errors, see 16 common iOS code signing and .ipa install errors.