vuls: init at 0.27.0
[NixPkgs.git] / doc / languages-frameworks / ios.section.md
blobeb8e2ca55326767381997463c5ff3c4d75415aef
1 # iOS {#ios}
3 This component is basically a wrapper/workaround that makes it possible to
4 expose an Xcode installation as a Nix package by means of symlinking to the
5 relevant executables on the host system.
7 Since Xcode can't be packaged with Nix, nor we can publish it as a Nix package
8 (because of its license) this is basically the only integration strategy
9 making it possible to do iOS application builds that integrate with other
10 components of the Nix ecosystem
12 The primary objective of this project is to use the Nix expression language to
13 specify how iOS apps can be built from source code, and to automatically spawn
14 iOS simulator instances for testing.
16 This component also makes it possible to use [Hydra](https://nixos.org/hydra),
17 the Nix-based continuous integration server to regularly build iOS apps and to
18 do wireless ad-hoc installations of enterprise IPAs on iOS devices through
19 Hydra.
21 The Xcode build environment implements a number of features.
23 ## Deploying a proxy component wrapper exposing Xcode {#deploying-a-proxy-component-wrapper-exposing-xcode}
25 The first use case is deploying a Nix package that provides symlinks to the Xcode
26 installation on the host system. This package can be used as a build input to
27 any build function implemented in the Nix expression language that requires
28 Xcode.
30 ```nix
31 let
32   pkgs = import <nixpkgs> {};
34   xcodeenv = import ./xcodeenv {
35     inherit (pkgs) stdenv;
36   };
38 xcodeenv.composeXcodeWrapper {
39   version = "9.2";
40   xcodeBaseDir = "/Applications/Xcode.app";
42 ```
44 By deploying the above expression with `nix-build` and inspecting its content
45 you will notice that several Xcode-related executables are exposed as a Nix
46 package:
48 ```bash
49 $ ls result/bin
50 lrwxr-xr-x  1 sander  staff  94  1 jan  1970 Simulator -> /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/Contents/MacOS/Simulator
51 lrwxr-xr-x  1 sander  staff  17  1 jan  1970 codesign -> /usr/bin/codesign
52 lrwxr-xr-x  1 sander  staff  17  1 jan  1970 security -> /usr/bin/security
53 lrwxr-xr-x  1 sander  staff  21  1 jan  1970 xcode-select -> /usr/bin/xcode-select
54 lrwxr-xr-x  1 sander  staff  61  1 jan  1970 xcodebuild -> /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
55 lrwxr-xr-x  1 sander  staff  14  1 jan  1970 xcrun -> /usr/bin/xcrun
56 ```
58 ## Building an iOS application {#building-an-ios-application}
60 We can build an iOS app executable for the simulator, or an IPA/xcarchive file
61 for release purposes, e.g. ad-hoc, enterprise or store installations, by
62 executing the `xcodeenv.buildApp {}` function:
64 ```nix
65 let
66   pkgs = import <nixpkgs> {};
68   xcodeenv = import ./xcodeenv {
69     inherit (pkgs) stdenv;
70   };
72 xcodeenv.buildApp {
73   name = "MyApp";
74   src = ./myappsources;
75   sdkVersion = "11.2";
77   target = null; # Corresponds to the name of the app by default
78   configuration = null; # Release for release builds, Debug for debug builds
79   scheme = null; # -scheme will correspond to the app name by default
80   sdk = null; # null will set it to 'iphonesimulator` for simulator builds or `iphoneos` to real builds
81   xcodeFlags = "";
83   release = true;
84   certificateFile = ./mycertificate.p12;
85   certificatePassword = "secret";
86   provisioningProfile = ./myprovisioning.profile;
87   signMethod = "ad-hoc"; # 'enterprise' or 'store'
88   generateIPA = true;
89   generateXCArchive = false;
91   enableWirelessDistribution = true;
92   installURL = "/installipa.php";
93   bundleId = "mycompany.myapp";
94   appVersion = "1.0";
96   # Supports all xcodewrapper parameters as well
97   xcodeBaseDir = "/Applications/Xcode.app";
99 ```
101 The above function takes a variety of parameters:
103 * The `name` and `src` parameters are mandatory and specify the name of the app
104   and the location where the source code resides
105 * `sdkVersion` specifies which version of the iOS SDK to use.
107 It also possible to adjust the `xcodebuild` parameters. This is only needed in
108 rare circumstances. In most cases the default values should suffice:
110 * Specifies which `xcodebuild` target to build. By default it takes the target
111   that has the same name as the app.
112 * The `configuration` parameter can be overridden if desired. By default, it
113   will do a debug build for the simulator and a release build for real devices.
114 * The `scheme` parameter specifies which `-scheme` parameter to propagate to
115   `xcodebuild`. By default, it corresponds to the app name.
116 * The `sdk` parameter specifies which SDK to use. By default, it picks
117   `iphonesimulator` for simulator builds and `iphoneos` for release builds.
118 * The `xcodeFlags` parameter specifies arbitrary command line parameters that
119   should be propagated to `xcodebuild`.
121 By default, builds are carried out for the iOS simulator. To do release builds
122 (builds for real iOS devices), you must set the `release` parameter to `true`.
123 In addition, you need to set the following parameters:
125 * `certificateFile` refers to a P12 certificate file.
126 * `certificatePassword` specifies the password of the P12 certificate.
127 * `provisioningProfile` refers to the provision profile needed to sign the app
128 * `signMethod` should refer to `ad-hoc` for signing the app with an ad-hoc
129   certificate, `enterprise` for enterprise certificates and `app-store` for App
130   store certificates.
131 * `generateIPA` specifies that we want to produce an IPA file (this is probably
132   what you want)
133 * `generateXCArchive` specifies that we want to produce an xcarchive file.
135 When building IPA files on Hydra and when it is desired to allow iOS devices to
136 install IPAs by browsing to the Hydra build products page, you can enable the
137 `enableWirelessDistribution` parameter.
139 When enabled, you need to configure the following options:
141 * The `installURL` parameter refers to the URL of a PHP script that composes the
142   `itms-services://` URL allowing iOS devices to install the IPA file.
143 * `bundleId` refers to the bundle ID value of the app
144 * `appVersion` refers to the app's version number
146 To use wireless adhoc distributions, you must also install the corresponding
147 PHP script on a web server (see section: 'Installing the PHP script for wireless
148 ad hoc installations from Hydra' for more information).
150 In addition to the build parameters, you can also specify any parameters that
151 the `xcodeenv.composeXcodeWrapper {}` function takes. For example, the
152 `xcodeBaseDir` parameter can be overridden to refer to a different Xcode
153 version.
155 ## Spawning simulator instances {#spawning-simulator-instances}
157 In addition to building iOS apps, we can also automatically spawn simulator
158 instances:
160 ```nix
162   pkgs = import <nixpkgs> {};
164   xcodeenv = import ./xcodeenv {
165     inherit (pkgs) stdenv;
166   };
168 xcode.simulateApp {
169   name = "simulate";
171   # Supports all xcodewrapper parameters as well
172   xcodeBaseDir = "/Applications/Xcode.app";
176 The above expression produces a script that starts the simulator from the
177 provided Xcode installation. The script can be started as follows:
179 ```bash
180 ./result/bin/run-test-simulator
183 By default, the script will show an overview of UDID for all available simulator
184 instances and asks you to pick one. You can also provide a UDID as a
185 command-line parameter to launch an instance automatically:
187 ```bash
188 ./result/bin/run-test-simulator 5C93129D-CF39-4B1A-955F-15180C3BD4B8
191 You can also extend the simulator script to automatically deploy and launch an
192 app in the requested simulator instance:
194 ```nix
196   pkgs = import <nixpkgs> {};
198   xcodeenv = import ./xcodeenv {
199     inherit (pkgs) stdenv;
200   };
202 xcode.simulateApp {
203   name = "simulate";
204   bundleId = "mycompany.myapp";
205   app = xcode.buildApp {
206     # ...
207   };
209   # Supports all xcodewrapper parameters as well
210   xcodeBaseDir = "/Applications/Xcode.app";
214 By providing the result of an `xcode.buildApp {}` function and configuring the
215 app bundle id, the app gets deployed automatically and started.
217 ## Troubleshooting {#troubleshooting}
219 In some rare cases, it may happen that after a failure, changes are not picked
220 up. Most likely, this is caused by a derived data cache that Xcode maintains.
221 To wipe it you can run:
223 ```bash
224 $ rm -rf ~/Library/Developer/Xcode/DerivedData