xref: /aosp_15_r20/external/webrtc/docs/native-code/ios/index.md (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1# WebRTC iOS development
2
3## Development Environment
4
5In case you need to build the framework manually or you want to try out the
6demo application AppRTCMobile, follow the instructions illustrated bellow.
7
8A macOS machine is required for iOS development. While it's possible to
9develop purely from the command line with text editors, it's easiest to use
10Xcode. Both methods will be illustrated here.
11
12_NOTICE:_ You will need to install [Chromium depot_tools][webrtc-prerequisite-sw].
13
14## Getting the Code
15
16Create a working directory, enter it, and run:
17
18```
19$ fetch --nohooks webrtc_ios
20$ gclient sync
21```
22
23This will fetch a regular WebRTC checkout with the iOS-specific parts
24added. Notice the size is quite large: about 6GB. The same checkout can be used
25for both Mac and iOS development, since GN allows you to generate your
26[Ninja][ninja] project files in different directories for each build config.
27
28You may want to disable Spotlight indexing for the checkout to speed up
29file operations.
30
31Note that the git repository root is in `src`.
32
33From here you can check out a new local branch with:
34
35```
36$ git new-branch <branch name>
37```
38
39See [Development][webrtc-development] for generic instructions on how
40to update the code in your checkout.
41
42
43## Generating project files
44
45[GN][gn] is used to generate [Ninja][ninja] project files. In order to configure
46[GN][gn] to generate build files for iOS certain variables need to be set.
47Those variables can be edited for the various build configurations as needed.
48
49The variables you should care about are the following:
50
51* `target_os`:
52  - To build for iOS this should be set as `target_os="ios"` in your `gn args`.
53  The default is whatever OS you are running the script on, so this can be
54  omitted when generating build files for macOS.
55* `target_cpu`:
56  - For builds targeting iOS devices, this should be set to either `"arm"` or
57  `"arm64"`, depending on the architecture of the device. For builds to run in
58  the simulator, this should be set to `"x64"`.
59* `is_debug`:
60  - Debug builds are the default. When building for release, specify `false`.
61
62The component build is the default for Debug builds, which are also enabled by
63default unless `is_debug=false` is specified.
64
65The [GN][gn] command for generating build files is `gn gen <output folder>`.
66
67After you've generated your build files once, subsequent invocations of `gn gen`
68with the same output folder will use the same arguments as first supplied.
69To edit these at any time use `gn args <output folder>`. This will open up
70a file in `$EDITOR` where you can edit the arguments. When you've made
71changes and save the file, `gn` will regenerate your project files for you
72with the new arguments.
73
74### Examples
75
76```
77$ # debug build for 64-bit iOS
78$ gn gen out/ios_64 --args='target_os="ios" target_cpu="arm64"'
79
80$ # debug build for simulator
81$ gn gen out/ios_sim --args='target_os="ios" target_cpu="x64"'
82```
83
84## Compiling with ninja
85
86To compile, just run ninja on the appropriate target. For example:
87
88```
89$ ninja -C out/ios_64 AppRTCMobile
90```
91
92Replace `AppRTCMobile` in the command above with the target you
93are interested in.
94
95To see a list of available targets, run `gn ls out/<output folder>`.
96
97## Using Xcode
98
99Xcode is the default and preferred IDE to develop for the iOS platform.
100
101*Generating an Xcode project*
102
103To have GN generate Xcode project files, pass the argument `--ide=xcode`
104when running `gn gen`. This will result in a file named `all.xcodeproj`
105placed in your specified output directory.
106
107Example:
108
109```
110$ gn gen out/ios --args='target_os="ios" target_cpu="arm64"' --ide=xcode
111$ open -a Xcode.app out/ios/all.xcodeproj
112```
113
114*Compile and run with Xcode*
115
116Compiling with Xcode is not supported! What we do instead is compile using a
117script that runs ninja from Xcode. This is done with a custom _run script_
118action in the build phases of the generated project. This script will simply
119call ninja as you would when building from the command line.
120
121This gives us access to the usual deployment/debugging workflow iOS developers
122are used to in Xcode, without sacrificing the build speed of Ninja.
123
124## Running the tests
125
126There are several test targets in WebRTC. To run the tests, you must deploy the
127`.app` bundle to a device (see next section) and run them from there.
128To run a specific test or collection of tests, normally with gtest one would pass
129the `--gtest_filter` argument to the test binary when running. To do this when
130running the tests from Xcode, from the targets menu, select the test bundle
131and press _edit scheme..._ at the bottom of the target dropdown menu. From there
132click _Run_ in the sidebar and add `--gtest_filter` to the _Arguments passed on
133Launch_ list.
134
135If deploying to a device via the command line using [`ios-deploy`][ios-deploy],
136use the `-a` flag to pass arguments to the executable on launch.
137
138## Deploying to Device
139
140It's easiest to deploy to a device using Xcode. Other command line tools exist
141as well, e.g. [`ios-deploy`][ios-deploy].
142
143**NOTICE:** To deploy to an iOS device you must have a valid signing identity
144set up. You can verify this by running:
145
146```
147$ xcrun security find-identity -v -p codesigning
148```
149
150If you don't have a valid signing identity, you can still build for ARM,
151but you won't be able to deploy your code to an iOS device. To do this,
152add the flag `ios_enable_code_signing=false` to the `gn gen` args when you
153generate the build files.
154
155## Using WebRTC in your app
156
157To build WebRTC for use in a native iOS app, it's easiest to build
158`WebRTC.framework`. This can be done with ninja as follows, replacing `ios`
159with the actual location of your generated build files.
160
161```
162ninja -C out/ios framework_objc
163```
164
165This should result in a `.framework` bundle being generated in `out/ios`.
166This bundle can now be directly included in another app.
167
168If you need a FAT `.framework`, that is, a binary that contains code for
169multiple architectures, and will work both on device and in the simulator,
170a script is available [here][framework-script]
171
172The resulting framework can be found in out_ios_libs/.
173
174Please note that you can not ship the FAT framework binary with your app
175if you intend to distribute it through the app store.
176To solve this either remove "x86-64" from the list of architectures in
177the [build script][framework-script] or split the binary and recreate it without x86-64.
178For instructions on how to do this see [here][strip-arch].
179
180
181[cocoapods]: https://cocoapods.org/pods/GoogleWebRTC
182[webrtc-prerequisite-sw]: https://webrtc.googlesource.com/src/+/main/docs/native-code/development/prerequisite-sw/index.md
183[webrtc-development]: https://webrtc.googlesource.com/src/+/main/docs/native-code/development/index.md
184[framework-script]: https://webrtc.googlesource.com/src/+/main/tools_webrtc/ios/build_ios_libs.py
185[ninja]: https://ninja-build.org/
186[gn]: https://gn.googlesource.com/gn/+/main/README.md
187[ios-deploy]: https://github.com/phonegap/ios-deploy
188[strip-arch]: http://ikennd.ac/blog/2015/02/stripping-unwanted-architectures-from-dynamic-libraries-in-xcode/
189