You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jan 19, 2025. It is now read-only.
In a [previous post](/2018/07/04/react-native-typescript-existing-app.html"react native typescript") I talked about
22
-
the "app relaunch" project I was involved in the last few months at [lastminute.com group](https://lmgroup.lastminute.com/"lastminute.com group").
23
-
During one of the last sprint before the release we started to think about putting in place an internal beta testing
24
-
program to have more testing data and eventually discover more bugs before the release on the App Store (we really
25
-
wanted to eat our food :smile:). We thought about using the TestFlight environment with external testers. But this solution didn't work for us because:
21
+
In a [previous post](/2018/07/04/react-native-typescript-existing-app.html"react native typescript") I talked about the "app relaunch" project I was involved in the last few months at [lastminute.com group](https://lmgroup.lastminute.com/"lastminute.com group"). During one of the last sprint before the release we started to think about putting in place an internal beta testing program to have more testing data and eventually discover more bugs before the release on the App Store (we really wanted to eat our food :smile:). We thought about using the TestFlight environment with external testers. But this solution didn't work for us because:
26
22
27
23
* we wanted to let everyone in the company be able to install the beta version without the need for any kind of registration. The external testers in the TestFlight environment must be registered in the "External Tester" section of you app in the App Store Connect (someone said iTunes Connect?!?!?! :stuck_out_tongue_closed_eyes:).
28
24
* we wanted to associate the beta with a new bundle id so that we could have a custom monitoring section in the [Fabric](https://get.fabric.io/"Fabric") dashboard.
@@ -35,51 +31,35 @@ I worked on the creation of this custom internal Beta distribution program with
35
31
ever met :cupid::sparkling_heart:.
36
32
So how did we decide to proceed? We basically did the following operation to put in place our beta program:
37
33
38
-
* Create a new bundle identifier and a new provisioning profile in our enterprise account.
39
-
* Create inside our app a new configuration with some customization for the Beta build.
40
-
* Add some new scripts to automatize the creation and the upload of new beta ipa using [Fastlane](https://fastlane.tools/"App Release Automation Fastlane"),
41
-
Jenkins (CI), maven (for the upload) and Nexus as our repository manger (we already use all these platforms for the
42
-
distribution of our release version and to store development snapshots of the ipa).
43
-
* Put in place a mini website, configured specifically for the distribution of the beta app.
44
-
45
-
To show you the details and some screenshots of the operation we made I will use a sample project `SampleBetaApp`
46
-
with bundle identifier `it.chicio.SampleBetaApp`.
47
-
Let's start from the first step: configuration on the Apple developer account for our new enterprise program. As
48
-
already explained before, we decided to create a new bundle identifier for the beta app and obviously a new provisioning profile. The procedure is
49
-
basically the same of the standard program for both the bundle identifier and the provisioning profile. We just need
50
-
to follow the instruction in the Apple Developer Account site in the section "Certificates, Identities & Profiles"
51
-
(and maybe there's a high chance that, if you're reading this post you already release at least one app on the
52
-
Apple app store so you already know the stuff to do :smirk:).
34
+
* Create a new bundle identifier and a new provisioning profile in our enterprise account.
35
+
* Create inside our app a new configuration with some customization for the Beta build.
36
+
* Add some new scripts to automatize the creation and the upload of new beta ipa using [Fastlane](https://fastlane.tools/"App Release Automation Fastlane"), Jenkins (CI), maven (for the upload) and Nexus as our repository manger (we already use all these platforms for the distribution of our release version and to store development snapshots of the ipa).
37
+
* Put in place a mini website, configured specifically for the distribution of the beta app.
38
+
39
+
To show you the details and some screenshots of the operation we made I will use a sample project `SampleBetaApp` with bundle identifier `it.chicio.SampleBetaApp`.
40
+
Let's start from the first step: configuration on the Apple developer account for our new enterprise program. As already explained before, we decided to create a new bundle identifier for the beta app and obviously a new provisioning profile. The procedure is basically the same of the standard program for both the bundle identifier and the provisioning profile. We just need to follow the instruction in the Apple Developer Account site in the section "Certificates, Identities & Profiles" (and maybe there's a high chance that, if you're reading this post you already release at least one app on the Apple app store so you already know the stuff to do :smirk:).
53
41
54
-
{% include blog-lazy-image.html description="enterprise profiles" width="920" height="547" src="/assets/images/posts/enterprise-profiles.jpg" %}
42
+
{% include blog-lazy-image.html description="Certificates, Identities & Profiles section on the developer Apple website" width="920" height="547" src="/assets/images/posts/enterprise-profiles.jpg" %}
55
43
56
44
After that we created in our iOS project a new Beta configuration by duplicating the release one. In this way we were able to generate an ipa similar to the release one and were also able to customize some settings of our app.
57
45
58
-
{% include blog-lazy-image.html description="beta configuration" width="920" height="561" src="/assets/images/posts/beta-configuration.jpg" %}
46
+
{% include blog-lazy-image.html description="Add a new beta build configuration" width="920" height="561" src="/assets/images/posts/beta-configuration.jpg" %}
59
47
60
48
The Build Setting that we customized are:
61
49
62
-
* Obviously the bundle identifier. Here we used the one created in the first step (Apple Enterprise developer
63
-
Account configuration). The entry that we modified in the Build settings is named "Product Bundle Identifier".
50
+
* Obviously the bundle identifier. Here we used the one created in the first step (Apple Enterprise developer Account configuration). The entry that we modified in the Build settings is named "Product Bundle Identifier".
64
51
65
-
{% include blog-lazy-image.html description="beta bundle identifier" width="920" height="547" src="/assets/images/posts/beta-bundle-identifier.jpg" %}
52
+
{% include blog-lazy-image.html description="Set a new product identifier for the beta build" width="920" height="547" src="/assets/images/posts/beta-bundle-identifier.jpg" %}
66
53
67
54
* The app icon. You can add a new asset in your main assets catalog. The entry that we modified in the Build settings is named "Asset Catalog App Icon Set Name".
68
55
69
-
{% include blog-lazy-image.html description="beta icon" width="920" height="547" src="/assets/images/posts/beta-icon.jpg" %}
56
+
{% include blog-lazy-image.html description="Set a new icon for the beta build" width="920" height="547" src="/assets/images/posts/beta-icon.jpg" %}
70
57
71
-
* We added a new custom preprocessor macro in the "Preprocessor Macros" build setting to be able to detect in our
72
-
source code that we are running a beta version and eventually do some custom stuff. For example we added the build
73
-
version number in the about section only for the beta version. In this way our tester were able to tell us exactly
74
-
which version they were using. This macro is visible only to Objective-C. If you need to do the same thing in Swift
75
-
you need to customize the "Other Swift Flags" field.
58
+
* We added a new custom preprocessor macro in the "Preprocessor Macros" build setting to be able to detect in our source code that we are running a beta version and eventually do some custom stuff. For example we added the build version number in the about section only for the beta version. In this way our tester were able to tell us exactly which version they were using. This macro is visible only to Objective-C. If you need to do the same thing in Swift you need to customize the "Other Swift Flags" field.
76
59
77
-
{% include blog-lazy-image.html description="beta preprocessor macro" width="920" height="547" src="/assets/images/posts/beta-preprocessor-macro.jpg" %}
60
+
{% include blog-lazy-image.html description="Set a new beta preprocessor macro" width="920" height="547" src="/assets/images/posts/beta-preprocessor-macro.jpg" %}
78
61
79
-
Then we created the scripts needed to automatize the build on Jenkins and the upload of our artifacts repository to
80
-
Nexus. As I said before we were already using Fastlane to automatize the releases of our app to the store. For the beta
81
-
publishing process we decided to create a new lane in our Fastfile where we launch a custom script to do all the operation
82
-
needed to publish our beta.
62
+
Then we created the scripts needed to automatize the build on Jenkins and the upload of our artifacts repository to Nexus. As I said before we were already using Fastlane to automatize the releases of our app to the store. For the beta publishing process we decided to create a new lane in our Fastfile where we launch a custom script to do all the operation needed to publish our beta.
83
63
84
64
```bash
85
65
lane :create_beta_ipa do|options|
@@ -89,17 +69,9 @@ end
89
69
90
70
As you can see below, in the script `build_beta.sh` we do three things:
91
71
92
-
* We generate an archive of our app using the `xcodebuild archive` command using the Beta configuration we
93
-
created before. We customized some other options. For example the archive path. At the end of this command we obtain a
94
-
file named `SampleBetaApp.xcarchive` in the folder `<project root>/DerivedData/Beta`.
95
-
* Then we exporte the ipa by using the `xcodebuild -exportArchive` command. This command needs and
96
-
`exportOptionsPlist` file that contains some exporting options, including the provisioning profile name that must
97
-
corresponds to the name of the provisioning profile we created at the beginning in the Apple Enterprise Developer
98
-
account. Below the script you can find the `exportOptions-SampleBetaApp.plist` sample file for the `SampleBetaApp` project.
99
-
* Last but not least, when the ipa is ready we upload it on Nexus using Maven (in the script below you can find some
100
-
placeholder for some of the parameter used :wink:). The command is simple and clear: we are uploading our artifact,
101
-
the ipa, without generating any pom version. One important thing to note: we use always 1 as version, because we
102
-
decided that we don't want to store the beta versions history. We just want to keep the last one we publish.
72
+
* We generate an archive of our app using the `xcodebuild archive` command using the Beta configuration we created before. We customized some other options. For example the archive path. At the end of this command we obtain a file named `SampleBetaApp.xcarchive` in the folder `<project root>/DerivedData/Beta`.
73
+
* Then we exported the ipa by using the `xcodebuild -exportArchive` command. This command needs and `exportOptionsPlist` file that contains some exporting options, including the provisioning profile name that must corresponds to the name of the provisioning profile we created at the beginning in the Apple Enterprise Developer account. Below the script you can find the `exportOptions-SampleBetaApp.plist` sample file for the `SampleBetaApp` project.
74
+
* Last but not least, when the ipa is ready we upload it on Nexus using Maven (in the script below you can find some placeholder for some of the parameter used :wink:). The command is simple and clear: we are uploading our artifact, the ipa, without generating any pom version. One important thing to note: we use always 1 as version, because we decided that we don't want to store the beta versions history. We just want to keep the last one we publish.
103
75
104
76
```bash
105
77
#!/usr/bin/env bash
@@ -128,7 +100,7 @@ mvn deploy:deploy-file -DgroupId="<group id project identifier>"
128
100
-DrepositoryId=nexus
129
101
-Durl="<nexus repository url>"
130
102
-Dfile="$IPA"
131
-
```
103
+
```
132
104
133
105
```xml
134
106
<?xml version="1.0" encoding="UTF-8"?>
@@ -146,16 +118,11 @@ mvn deploy:deploy-file -DgroupId="<group id project identifier>"
146
118
</dict>
147
119
</dict>
148
120
</plist>
149
-
```
121
+
```
150
122
151
123
At this moment we were ready to create the new Jenkins job to build our beta. We decided to trigger it using Jenkins
152
-
webhook triggers. In this way we were able to trigger the build and release of a new beta by just calling an url. This
153
-
job basically clone our app repository and then execute the lane `create_beta_ipa` that we defined before in the
154
-
Fastlane Fastfile.
155
-
So in the end with all this steps above we obtained an ipa reachable at a public url (on Nexus). We decided to publish
156
-
our beta using Github Pages (the same service that runs this website :hearts:). Why? Because we needed a server with HTTPS
157
-
already configured. Github pages let us create the beta website really fast. So we created a new account and
158
-
published a new html that contains the following code:
124
+
webhook triggers. In this way we were able to trigger the build and release of a new beta by just calling an url. This job basically clone our app repository and then execute the lane `create_beta_ipa` that we defined before in the Fastlane Fastfile.
125
+
So in the end with all this steps above we obtained an ipa reachable at a public url (on Nexus). We decided to publish our beta using Github Pages (the same service that runs this website :hearts:). Why? Because we needed a server with HTTPS already configured. Github pages let us create the beta website really fast. So we created a new account and published a new html that contains the following code:
159
126
160
127
```html
161
128
<html>
@@ -173,13 +140,7 @@ published a new html that contains the following code:
173
140
</html>
174
141
```
175
142
176
-
As you can see above, in this html there's a special link with the protocol `itms-services`. If a user clicks on this
177
-
link from Safari browser on a iOS device, the download and the installation of the app will starts. If you look
178
-
carefully at the content of the link above, you will notice there's a reference to a url of a **manifest.plist**
179
-
file. This is a file generated by Xcode if you export an archive with an enteprise certificate and contains some
180
-
metadata for the ipa, including the location/url of the ipa to be downloaded. In our case this url was the Nexus
181
-
link to the ipa. This file can be generated the first time and eventually edited if there's any change. This is a
182
-
sample manifest file that could be used for our SampleBetaApp.
143
+
As you can see above, in this html there's a special link with the protocol `itms-services`. If a user clicks on this link from Safari browser on a iOS device, the download and the installation of the app will starts. If you look carefully at the content of the link above, you will notice there's a reference to a url of a **manifest.plist** file. This is a file generated by Xcode if you export an archive with an enteprise certificate and contains some metadata for the ipa, including the location/url of the ipa to be downloaded. In our case this url was the Nexus link to the ipa. This file can be generated the first time and eventually edited if there's any change. This is a sample manifest file that could be used for our SampleBetaApp.
183
144
184
145
```xml
185
146
<?xml version="1.0" encoding="UTF-8"?>
@@ -229,6 +190,6 @@ As you can see above, in this html there's a special link with the protocol `itm
229
190
230
191
Now we were ready to distribute our beta app, and you know everything is needed to create your own beta program. One last thing: you will need to explain to the less experienced user that they need to accept the enterprise provisioning profile from *Settings -> Profiles & Device Management*. If they don't do it they will see the alert contained in the screenshot below.
231
192
232
-
{% include blog-lazy-image.html description="enterprise untrusted developer" width="1500" height="1000" src="/assets/images/posts/enterprise-untrusted-developer.jpg" %}
193
+
{% include blog-lazy-image.html description="You need to accept the developer certificate before using the app" width="1500" height="1000" src="/assets/images/posts/enterprise-untrusted-developer.jpg" %}
233
194
234
195
That's it!!! Go to your boss and tell her/him you're ready to create you custom iOS beta internal program!!! :sunglasses::apple:
0 commit comments