# Creating React Native Simulator Builds in App Center

Using App Center for mobile CI/CD is simple, but it does not allow for much customization. Our team requested a simulator build to facilitate automated testing. After some research and tinkering, I was able to come up with a clever (read: hacky) solution.

Ben Lokash

Sep 22, 2022

·

3 min read

[technology](/content/blog_filter-technology/index.html)

##### Table of contents:

[Adding the build pipelines](/content/blog/creating-react-native-simulator-builds-in-app-center#adding-the-build-pipelines/index.html)

[Pre-build Script](/content/blog/creating-react-native-simulator-builds-in-app-center#pre-build-script/index.html)
- [Branching paths in appcenter-pre-build.sh](/content/blog/creating-react-native-simulator-builds-in-app-center#branching-paths-in-appcenter-pre-build-sh/index.html)
- [The simulator build script](/content/blog/creating-react-native-simulator-builds-in-app-center#the-simulator-build-script/index.html)
- [xcodebuild](/content/blog/creating-react-native-simulator-builds-in-app-center#xcodebuild/index.html)
- [AppCenter Distribution](/content/blog/creating-react-native-simulator-builds-in-app-center#appcenter-distribution/index.html)

[Conclusion](/content/blog/creating-react-native-simulator-builds-in-app-center#conclusion/index.html)

I generally like using App Center for mobile CI/CD. It is dead simple to get a pipeline up and running. However, it does not allow for much customization. I recently ran up against this limitation when trying to set up a build pipeline for iOS simulator builds.

Our QA team requested a `.app` build to facilitate automated testing. I quickly realized that App Center did not support this - the default build config results in a `.ipa` file for installing on physical devices. After some research and tinkering, I was able to come up with a clever (read: hacky) solution.

The general idea is:

1. Create the `.app` artifact by running `xcodebuild` in a pre-build script

2. Distribute the artifact using the App Center CLI

3. Exit the build before the usual build steps run

### Adding the build pipelines

We are going to set up two pipelines, one for building the app, and one for distribution. The reason we need a separate pipeline for distributions is that the standard iOS OS type in App Center will only let you distribute `.ipa` files when what we need is `.app`. We can get around this by creating a second pipeline using the “Custom” option for our OS. The custom OS type will let you distribute `.zip` files, which will allow us to distribute our `.app` files - all we have to do is compress them before uploading.

The first pipeline should be configured the same as any other iOS build pipeline you may have already set up. Set an environment variable (eg. `$IS_CI_SIMULATOR_BUILD`) that we can use later in the build script to run the simulator build instead of the regular one.

The second will be a “Custom” app type, which has no build step but lets us distribute `.zip` files, which will contain our `.app` artifact.

We will also need to create an authentication token. We will use this later to authenticate with the App Center CLI in order to upload our build.

### Pre-build Script

#### Branching paths in appcenter-pre-build.sh

```bash
if [[ $IS_CI_SIMULATOR_BUILD ]]; then
  bash ./scripts/ios-sim-build.sh
fi
```

Our codebase should be build-agnostic, so we can use an environment variable to tell App Center to run our simulator build script at the end of the regular build script.

We also need to add an additional environment variable to our _build_ pipeline called `$APPCENTER_OWNER_APP_NAME` . You can find this value by going to the releases page of your _release_ pipeline. The url should be in the following format: `https://appcenter.ms/orgs/${YOUR_ORG}/apps/${YOUR_RELEASE_PIPELINE_NAME}/distribute/releases` Combine the two like so `$(YOUR_ORG}/${YOUR_RELEASE_PIPELINE_NAME}` to get a string that will uniquely identify the release pipeline.

#### The simulator build script

```bash
#!/usr/bin/env bash
unset PREFIX

cd ios && pod install && cd ..

xcodebuild -workspace "ios/MyApp.xcworkspace" \
  -derivedDataPath "./ios-sim-build" \
  -scheme "MyApp" \
  -configuration "Release" \
  -destination "generic/platform=iOS Simulator" \
  clean build

appcenter login --token $APPCENTER_USER_TOKEN

export BUILD_VERSION=`appcenter distribute releases list --app $APPCENTER_OWNER_APP_NAME | sed -n '1p' | sed "s/[^0-9]//g"`

# path may be different based on the name of your configuration
cd ios-sim-build/Build/Products/qa-iphonesimulator
zip -rq MyApp.zip MyApp.app

appcenter distribute release \
  --app $APPCENTER_OWNER_APP_NAME \
  --file PayPower.zip \
  --group "QA"
  --build-version $(($BUILD_VERSION + 1))

exit
```

#### xcodebuild

- Ok, here’s the meat of the script:

- `xcodebuild` runs the build, resulting in the `.app` file we need.

- `-workspace`: path to the .xcworkspace file

- `-derivedDataPath`: path to the directory where the temp build files will be stored

- `-scheme`: usually the name of your project unless you have created custom schemes

- `-configuration`: usually `"Debug"` or `"Release"` unless you have created custom configurations. You probably want `Release` because it will include the bundled JS, whereas `Debug` will be looking for the metro server.

- `-destination`: use `"generic/platform=iOS Simulator"` as the value to get a `.app` artifact

- `clean` \+ `build`: clean cache files and start the build

#### AppCenter Distribution

- We’ve got our `.app` artifact. All we have to do now is find a way to distribute it!

- Authenticate using `appcenter login --token $APPCENTER_USER_TOKEN`

- Get the previous build number using `appcenter distribute releases list` and `sed`, so we can increment it and use it for the current release

- Zip the .app file

- Distribute using `appcenter distribute release`

- `exit` quits the builds early and shows a green checkmark

### Conclusion

After using this approach with my team for a few weeks, we identified some opportunities for improvement. We realized that the `.zips` don’t come with build numbers or versions attached. We plan on adding this information to the file name before rolling out this solution more widely across the project.

Creating this pipeline has allowed our QA team to stay perfectly in sync with the development team. Before this approach, we had to manually run a build every time there was a push to `develop`. This was time-consuming and error-prone. Now, builds are created automatically on every push, and QA is instantly notified. We think it is well worth spending the time to develop this for any React Native project that relies on automated testing.

written by

Ben LokashSenior Software Engineer, Quantum Mob

###### Enjoyed this post?

%20solution.&url=https://qmo.io/blog/creating-react-native-simulator-builds-in-app-center)

###### Newsletter Sign-up

Receive summaries directly in your inbox.

Email

Sign up

We are a Toronto-based end-to-end digital innovation firm with a passion for building beautiful & functional products that deliver results.

[Hire us](/content/contact/index.html)

You might also like

\\
\\
Blog\\
\\
How We Built Dealmap With React Native, Redux, and Realm](/content/blog/differences-between-react-native-and-react/index.html)

\\
\\
Blog\\
\\
Technologies You Should Consider in Your 2023 Tech Stack](/content/events/webinar-improve-your-customer-experience-through-web-accessibility-and-inclusion/index.html)

\\
\\
Blog\\
\\
Before You Build a Design System, Understand Your Needs](/content/blog/before-you-build-a-design-system-understand-your-needs/index.html)

\\
\\
Launch a new business\\
\\
Validate an idea and launch a new product.](/content/contact?intent=project&projectIntent=business/index.html) \\
\\
Improve existing software\\
\\
Fix performance and improve user experiences.](/content/contact?intent=project&projectIntent=software/index.html)

312 Adelaide St. W, Suite 800

Toronto, ON M5V 1R2

- [Careers](/content/about/index.html)
- [Thought Leadership](/content/insights/index.html)
- [Privacy Policy](/content/privacy/index.html)
- [Contact](/content/contact/index.html)

- [hello@qmo.io](mailto:hello@qmo.io)
- [1 (877) 797-1927](tel:18777971927)
