You can publish a NativeScript app in Google Play the same way you would release a purely native Android app.
Make sure that you have a .keystore
file to sign your app with. For more information, see How to create a .keystore file?
Build your project in release mode by running the following command:
ns build android --release \
--key-store-path <path-to-your-keystore> \
--key-store-password <your-key-store-password> \
--key-store-alias <your-alias-name> \
--key-store-alias-password <your-alias-password>
Note
At the end of <path-to-your-keystore>
you should also add the exact name of your keystore.
Example
ns build android --release --key-store-path C:\keystore\NativeScriptApp.keystore --key-store-password sample_password --key-store-alias NativeScriptApp --key-store-alias-password sample_password
ns build android --release --key-store-path ~/Desktop/keystore/NativeScriptApp.keystore --key-store-password sample_password --key-store-alias NativeScriptApp --key-store-alias-password sample_password
.apk
located at <app_name>/platforms/android/app/build/outputs/apk/<app_name>-release.apk
. 5. Publish your Android app by uploading the .apk
file to the Google Developer Console. For more information, see How to publish an Android app?Both Package Name, and Application Id, are unique identifiers, provided by you for your app.
R
.In the NativeScript framework, both are set to the applicationId
in app.gradle
. The NativeScript CLI build system will set them as the package
attribute in the generated project in platforms/android/src/main/AndroidManifest.xml
. In the app/App_Resources/Android/AndroidManifest.xml
it will use a placeholder: package="__PACKAGE__"
. Do not modify the package
attribute there.
Note
To edit the Package Name and the Application Id, modify the nativescript.config.ts
of your app and set the id
key. You may need to delete platforms/android
and rebuild using the CLI command ns prepare android
.
Read more about "ApplicationId versus PackageName".
This is the display name for your app. It is purely cosmetic but highly important. For example, it appears under the app icon. The value can be set via the App_Resources/Android/src/main/res/values/strings.xml
file. Creating your own strings.xml
will require population of the app_name
and title_activity_kimera
attributes explicitly, like so:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MyAppName</string>
<string name="title_activity_kimera">MyAppName</string>
</resources>
By default (or if the project lacks the values above) your application name is generated with the create
command (e.g. ns create testApp
will have app name testApp)
You can check out more information about the elements you can define in the AndroidManifest.xml
here.
App icons are defined similar to the app name. The icon name is defined in the app/App_Resources/Android/AndroidManifest.xml
file, as an android:icon="@drawable/icon"
attribute, on the <application>
element.
The actual .PNG icons stay at the Android resources in app/App_Resource/Android/<DPI>/icon.png
, DPIs:
directory | DPI | screen | size |
---|---|---|---|
drawable-ldpi | 120 | Low density screen | 36px x 36px |
drawable-mdpi | 160 | Medium density screen | 48px x 48px |
drawable-hdpi | 240 | High density screen | 72px x 72px |
drawable-xhdpi | 320 | Extra-high density screen | 96px x 96px |
drawable-xxhdpi | 480 | Extra-extra-high density screen | 144px x 144px |
drawable-xxxhdpi | 640 | Extra-extra-extra-high density screen | 192px x 192px |
Note
NativeScript supports adaptive icons on Android 8 and above (API 26+). No code changes are required - follow the Android guidelines for creating adaptive icons for your application.
Launch screens are essential as they provide a user's first experience with your mobile application. Based on Google's Material Design launch screens guidelines, there are two main types of launch screens:
Instead of displaying a blank white canvas while your app is loading, creating a launch screen will not only "fill the gap" but also provide the basic introduction for your users. These basic rules for creating both types of launch screens are good to follow to create a good first impression:
In NativeScript, your application template (created with ns create myApp
) ships with a basic launch screen template. In this article, we are going to introduce the workflow to create/modify your own launch screen.
The default template in NativeScript (created with ns create myApp
) provides you with a predefined splash_screen.xml file with the NativeScript logo on a blue background and with sample app icons. To modify that template and create your own launch screen using your own assets and design, you will need to access the files located under the app/App_Resources/Android folder. Let’s look at the various files and folders in App_Resources/Android and then look at the specific steps you’ll need to take to change them and configure your launch screen.
drawable folders: In your app/App_Resources/Android folder you will find a number of subfolders named drawable-X (where x is the different DPI for the different devices) These folders will store your properly scaled images for your app icons, launch screens and in app images (optional). Here is the full list of your drawable resources folders.
drawable-ldpi: Resources for low-density (ldpi) screens (~120dpi).
drawable-mdpi: Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
drawable-hdpi: Resources for high-density (hdpi) screens (~240dpi).
drawable-nodpi: Resources for all densities. These are density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen's density.
Important
In NativeScript this is the folder that holds splash_screen.xml – the file that creates your launch screen.
drawable-xdpi: Resources for extra-high-density (xhdpi) screens (~320dpi).
drawable-xxdpi: Resources for extra-extra-high-density (xxhdpi) screens (~480dpi).
drawable-xxxdpi: Resources for extra-extra-extra-high-density (xxxhdpi) uses (~640dpi). Use this for the launcher icon only.
values folder: XML files that contain simple values such as strings, integers, and colors. Here is the full list of the files that ship with the basic NativeScript template.
* **colors.xml**: XML file in which the app colors are declared.
* **strings.xml**: XML file in which the app string are declared.
* **styles.xml**: XML file in which the app styles are declared.
This file holds your `LaunchScreenTheme` style,
which you can customize to change the `splash_screen.xml` mentioned above.
Once your application is loaded, the `LaunchScreenTheme` is changed with the `AppTheme` style.
values-v21 folder: XML files that contain simple values, such as strings, integers, and colors. Used when you need to provide themes supported only on API Level 21+ (e.g., Theme.Material)
AndroidManifest.xml file: Every application must have an AndroidManifest.xml
file (with precisely that name) in its root directory. The manifest file presents essential information about your app to the Android system – information the system must have before it can run any of the app's code. In order to change your application icon file, you must modify the android:icon
key in the applcation
tag. <Comment: Please review to enure I did not create a technical error. The original text was sort of hard to understand.> The default app icon set up:
android:icon="@drawable/icon"
The code above will look for the file named icon.png in the drawable folder and will load the properly scaled image for the current device. <Comment: Please review my rewrite of the sentence above to ensure I did not create an error. You had "drawables folders" but the command referred to a single folder (not plural).>
Note
In AndroidManifest
you will find the following key:
<meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />
This key is used by NativeScript to change your LaunchScreenTheme
with AppTheme
when your application is loading.
In order to change the default NativeScript launch screen (defined in drawable-nodpi/splash_screen.xml
) and create your own, follow these steps:
"res://image-name"
). The default template app ships with three images: icon.png (used for app icon), logo.png (centered sample image) and background.png (image used to fill the background).The default splash_screen.xml with centered logo.png
and filled background.png
.
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="fill"
>
<item>
<bitmap android:gravity="fill" android:src="@drawable/background" />
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/logo" />
</item>
</layer-list>
The default NativeScript template ships with two themes: LaunchScreenTheme
(used for your initial launch) and AppTheme
(used for your main application).
Note
If your project comes with no folders values, values-v21 and/or drawable-xxx, you can create them manually and add the files needed accordingly. Or you can use the default set of styles and themes used in NativeScript.
Notice that you can NOT have custom folders inside your App_Resources. Only folders that are required by the Android convention <Comment: convention seems like the wrong word. Do you mean operating system?> are allowed and they must be created with the exact names provided (e.g., values, values-v21, drawable). When adding new folders in your App_Resources you should reset your platform folder.
ns platform remove android
ns platform add android
Once your launch screen is fully set, rebuild your application and your launch screen is ready. On some occasions, you might need to reset your platform folder as mentioned above.
These are automatically generated by the Android SDK tools for you.
In debug mode, you sign your app with a debug certificate. This certificate has a private key with a known password. The process is handled by the Android tooling.
You can read more at "Signing in Debug Mode".
The release certificate for Android is created by you; it does not have to be signed by a certificate authority. It is easier to create a release certificate for Android than it is for iOS. You should, however, be more careful with your certificate.
A few pitfalls are:
You can generate a private key for a release certificate using the keytool.
keytool -genkey -v \
-keystore <my-release-key>.keystore \
-alias <alias_name> \
-keyalg RSA \
-keysize 2048 \
-validity 10000
This will run an interactive session collecting information about your name, organization and most importantly — keystore and alias passwords.
You will need a developer account and you will need to log into the Google Play Developer Console.
Go to the All applications section and click the + Add new application button.
You will get prompted to provide the app title
You can then proceed with the store listings.
You can fill in app description, screenshots and so on.
You can also submit an APK. Read about how to obtain an APK from a NativeScript app.
We have already explained how the Application Id is set in your project, how icons are added to your app and how you can set the display name.
Before the build, you need to set two important things: the versionCode and the android:versionName.
When a build is uploaded, its versionCode should be larger than previous builds. A new build with a higher versionCode is considered an upgrade to builds that have a lower versionCode. The versionCode is an integer so you should carefully consider a strategy for versioning.
Both values are stored in app/App_Resources/Android/AndroidManifest.xml
.
Note
android:versionName
is a string value, which is used to represent the application version to the user whereas android:versionCode
, which is integer value showing version of the application code relative to the other versions. You can read more about "Versioning Your Applications".
In the app/App_Resources/Android/AndroidManifest.xml
, the versionCode and versionName appear as:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.nativescript.name"
android:versionCode="2"
android:versionName="1.1">
...
You can perform a full build and produce a signed APK using the NativeScript CLI:
ns build android --release \
--key-store-path <path-to-your-keystore> \
--key-store-password <your-key-store-password> \
--key-store-alias <your-alias-name> \
--key-store-alias-password <your-alias-password> \
--copy-to <apk-location>.apk
You can then use the produced <apk-location>.apk
for upload to Google Play.
Note
The recommended approach for reducing the app size by splitting it per architecture is the Android App Bundle which is supported out of the box through the --aab
NativeScript CLI flag.
If the recommended Android App Bundle approach is not applicable for you, an ABI split could be manually configured as an alternative. The ABI split approach will produce different apk files for the different architectures. To achieve this you need to enable ABI splits at app/App_Resources/Android/app.gradle
android {
....
defaultConfig {
....
ndk {
abiFilters.clear()
}
}
splits {
abi {
enable true //enables the ABIs split mechanism
reset() //reset the list of ABIs to be included to an empty string
include 'arm64-v8a', 'armeabi-v7a', 'x86'
universalApk true
}
}
....
Now you will need to upload all built apk files in Google Play Developer Console. To achieve this the different apks need to have different Version Codes otherwise Google Play won't allow adding them in the same version. To use different Version Codes you can add the following code in your App_Resources/Android/app.gradle
which will prefix the different architecture apk Version Codes with different prefixes:
project.ext.abiCodes = ['armeabi-v7a': 1, 'arm64-v8a': 2, 'x86': 3]
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def baseAbiVersionCode = project.ext.abiCodes.get(output.getFilter("ABI"), 0)
if (baseAbiVersionCode != null) {
output.versionCodeOverride = baseAbiVersionCode * 10000000 + variant.versionCode
}
}
}
To submit your app to the Google Play Developer Console:
You can read more about these stages at "Set up alpha/beta tests".
Once you upload your APK, it will go through a review. When approved, you can move it to production to make it available on Google Play.
Android App Bundle is a new publishing format that contains all the compiled code and resources of your app, but leaves the actual APK generation and signing to Google Play. The store then uses the app bundle to generate and serve optimized APKs based on the device configuration of the specific user. In general, the benefit of using Android App Bundles is that you no longer have to build, sign, and manage multiple APKs to support different devices, and users get smaller, more optimized downloads. For more information about the Android App Bundle, see the About Android App Bundles article in the official Android Developer documentation.
You can perform a full build and produce a signed AAB using the NativeScript CLI:
ns build android --release \
--key-store-path <path-to-your-keystore> \
--key-store-password <your-key-store-password> \
--key-store-alias <your-alias-name> \
--key-store-alias-password <your-alias-password> \
--aab \
--copy-to <aab-location>.aab
Warning
Filtering the target architectures does not reduce the app size, it just drops the support for the devices and emulators using the missing architecture.
By default, the generated aab
file supports all of the available device architectures - armeabi-v7a
, arm64-v8a
, x86
and x86_64
. This behavior can be overridden from your App_Resources/Android/app.gradle
's apiFilters
property:
android {
....
defaultConfig {
....
ndk {
abiFilters.clear()
abiFilters "x86_64", "x86", "arm64-v8a", "armeabi-v7a"
}
}
....
.aab
file Starting from NativeScript CLI 6.2.0, the Android App Bundle is supported out of the box by the ns run
command:
ns run android \
--key-store-path <path-to-your-keystore> \
--key-store-password <your-key-store-password> \
--key-store-alias <your-alias-name> \
--key-store-alias-password <your-alias-password> \
--aab
.aab
file before NativeScript 6.2 For older NativeScript version, in order to test the apk
files that Google Play will produce from the .aab
for a specific device you will need to use the Android bundletool
or upload to Google Play and use a test track.
If you use the bundletool
you should first generate an .apks
file that will later be used to deploy on a device.
java -jar <toolPath>/bundletool.jar build-apks \
--bundle=<somePath>/app.aab \
--output="<somePath>/my_app.apks" \
--ks=<path-to-keystore-file> \
--ks-pass=pass:<keystore-pass> \
--ks-key-alias=<key-alias> \
--key-pass=pass:<key-pass> \
Then you can install the application on a connected device by executing:
Note
Devices running Android 4.4 (API level 19) and lower don’t support downloading and installing split APKs. On such devices bundletool
will not be able to deploy the application. When the bundle is released Google Play will serve a single multi-APK to such devices.
java -jar <toolPath>/bundletool.jar install-apks \
--apks="somePath/my_app.apks" \
--device-id=<deviceId>
You can find more information about using Android bundletool
here.
You can perform a full build and produce a signed AAB using the NativeScript CLI:
ns build android --release \
--key-store-path <path-to-your-keystore> \
--key-store-password <your-key-store-password> \
--key-store-alias <your-alias-name> \
--key-store-alias-password <your-alias-password> \
--aab \
--copy-to <aab-location>.aab
Then you can use the produced file to upload it to Google Play Developer Console following the steps described in Google Android Developer Documentation.
Some tools allow the submission process to be automated - MIT Licensed one: fastlane. You can also hack your own scripts around the Google Play Developer API.
Once you successfully upload your APK, and it passes Google review, you will be able to move your APK to production, and it will go live on Google Play.
You can publish a NativeScript app in the App Store the same way you would release a purely native iOS app.
ns prepare ios --release
{app-name}/platforms/ios/{app-name}.xcworkspace
(or in {app-name}/platforms/ios/{app-name}.xcodeproj
if the project does not contain any native iOS libraries).The Bundle ID is a unique identifier, provided by you for your app. It uses reverse domain name notation. For example, the NativeScript CLI will use org.nativescript.<AppName>
as default. During ns create
you can provide the Bundle ID using the --appid <id>
option.
In iOS apps, the Bundle ID is stored in the CFBundleIdentifier
in the Info.plist
, but the NativeScript CLI will explicitly set this to the value of the id
key stored in the nativescript.config.ts
file in the root of your application.
Note
To edit the Bundle ID, edit the nativescript.config.ts
of your app and set the id
key.
The Bundle ID is used to precisely identify your app at various situations and plays an important role, when it is built and launched by the CLI, as well as when Provisioning Profiles and certificates are created in the Apple Member Center.
For more information consider the 'About Bundle IDs' section in the following article.
This is the display name for your app. It is purely cosmetic but highly important. For example, it will appear under the app icon. The value is stored in the app/App_Resources/iOS/Info.plist
file as the CFBundleDisplayName
key.
The NativeScript framework will use icons from app/App_Resources/iOS/
. All files from that folder are added as resources in the generated Xcode project in platforms/ios
.
App Store submissions will be rejected if certain icon files are not present. To ensure you have the required icons, you can consider the following Apple article: 'App Icons on iPad and iPhone'.
If you want to extend the default icon set, and you don't want to use the default naming, or you need finer control, you can use the app/App_Resources/iOS/Info.plist
. List the icons using CFBundleIconFiles
or CFBundleIcon
.
For example, listing icons using CFBundleIconFiles
:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- The full content of the Info.plist still should be here. -->
<key>CFBundleIconFiles</key>
<array>
<string>Icon@2x.png</string>
<string>Icon.png</string>
<string>Icon-Small@3x.png</string>
<string>Icon-Small@2x.png</string>
<string>Icon-Small.png</string>
<string>Icon-Small-50@2x.png</string>
<!-- etc -->
</array>
</dict>
</plist>
Launch screens are an essential part of your iOS app. This is the first thing your users see when they start your app.
The Springboard will play a subtle animation transitioning from the home screen to your app. In order to provide a pleasing experience, it's best to avoid a default that's entirely black or white.
The launch files are not a splash screen; instead, they are a way for the OS to quickly grab a preview image of your app and use it during the first ~300ms while your app is booting.
For design guidelines you can consider the following article provided by Apple.
Note
If you think that following these guidelines will result in a plain, boring launch image, you’re right. Remember, the launch image doesn’t provide you with an opportunity for artistic expression. It’s solely intended to enhance the user’s perception of your app as quick to launch and immediately ready for use.
App Store submissions will be rejected if certain launch files are not present. Make sure that when new iOS versions and devices are released that you update your launch files and accommodate the upcoming form factors.
If a customer runs your app on a device with a high resolution screen and your app is missing the launch screen file for that device, then iOS will render your app using a smaller resolution, degrading its quality:
Earlier iOS versions had to support a small range of form factors. Providing a different launch image per screen size was trivial. With the new devices released by Apple, the number of images that had to be provided increased. That's where Apple introduced the launch screen storyboard. The storyboard allows basic primitives such as images to be presented on the screen, and you can have dynamic layout using layout constraints. This makes it possible to design a single launch screen that fits well for all form factors.
The NativeScript framework default project has a Launch Screen Storyboard and Launch Images. In iOS8 and later, your app may use storyboards; your app can use launch images for devices that run earlier versions of iOS.
The images are placed, similar to the icons already mentioned, in app/App_Resources/iOS
. The default project template ships several Default-*.PNG
files there; you may consider changing them.
In iOS8 and later versions, your app will display its storyboard. If you want to use images on all devices, you can consider disabling the Launch Screen Storyboard. Instructions for how to do this are explained later in the next section.
Similar to the icons, you can use the UILaunchImageFile
and UILaunchImages
key in the app/App_Resources/iOS
.
The NativeScript framework will provide a Launch Screen Storyboard in platforms/ios/<YourAppName>/en.lproj/LaunchScreen.xib
, but does not yet provide a means to store it at app/App_Resources/iOS
. If you want to edit it you can use the .xcodeproj
generated in platforms/ios
. You will have to add it in source control. CLI rebuilds may overwrite it, so you will have to watch out for automatic changes in it when you commit.
To disable the default Launch Screen Storyboard, remove the UILaunchStoryboardName
from the app/App_Resources/iOS/Info.plist
:
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
This will force all supported launch screens to use the launch image.
Publishing your iOS app is an essential step in the development process and in order for your iOS application to be published successfully in the App Store, there are some requirements that need to be fulfilled. As described in iOS Human Interface Guidelines setting the following is mandatory:
In NativeScript, your application comes with predefined template settings and images for these steps. In this article, we are going to introduce the workflow to create your own launch screens.
Warning
Occasionally, the iOS operating system caches your application’s icons and launch screens. If you’re updating icons or launch screens and not seeing your changes, delete the application from your device or emulator and redeploy. If on a real device: remove platforms
folder from your project, delete app, restart device, redeploy.
Setting up launch screens depends on the version of iOS you are targeting. In iOS 7 and lower, the approach for creating the launch screen is to use static image resources. The drawback of this method is that the app developer will have to provide many different images, each with different resolution for each iOS device. In iOS 8 and above, the approach is to create a LaunchScreen.storyboard, which is much more powerful in terms of customization and is easier to maintain.
The default Hello-World project in NativeScript is provided with default settings that supports both approaches. When you build your app for devices with iOS lower then version 8, NativeScript will use the static images and when you use NativeScript to build your app for devices with iOS 8 and above, it will use the provided LaunchScreen.storyboard.
The default template in NativeScript (created with ns create myApp
) provides you with predefined AppIcons, launch images and a LaunchScreen.storyboard all with the NativeScript logo. To modify that template and create your own launch screen using your own assets and design, you will need the following:
app/App_Resources/iOS/Assets.xcassets: The resource that holds your image asset catalogs (for AppIcons, LaunchImages and LaunchScreen).
app/App_Resources/iOS/LaunchScreen.storyboard: Your default storyboard used for your launch screen (used in iOS versions 8+).
app/App_Resources/iOS/build.xcconfig: The resource that holds the references to the assets catalogs which will be used (optional: modify only if you change the name convention or introduce a new image asset catalog).
Xcode 7.1 or newer version (optional: needed only if you prefer WYSIWYG workflow for changing your images).
The workflow for creating your own launch screen can be handled from Xcode or manually in the NativeScript environment. In this article we are going to cover both the manual and the Xcode WYSIWYG approach.
In your app/App_Resources/iOS/Assets.xcassets you will find the following sub-folders:
AppIcon.appiconset: The resource that holds the images for your AppIcons (all iOS versions).
LaunchScreen.AspectFill.imageset: The resource that holds the background image for your LaunchScreen.storyboard.
LaunchScreen.Center.imageset: The resource that holds the centered image for your LaunchScreen.storyboard.
Open AppIcon.appiconset and change the default icons images with your own using the proper resolution for each image (e.g., icon-29.png should be 29px x 29px; icon-29@2x should be 58px x 58px; icon-29@3x should be 87px x 87px). If your images have different file names then open Contents.json and change the key filename
for each image.
Drag and drop your Assets.xcassets into Xcode (7.1 or newer version). In the opened window choose AppIcon and add a proper image for each iOS version and device. Close Xcode and rebuild your NativeScript app to use the new AppIcons.
Open LaunchImage.launchimage and change the default launch images with your own using the proper resolution for each image (e.g., Default-568h@2x.png should be 640px x 1136px). If your images have different file names then open Contents.json and change the key filename
for each image.
Device | Image Resolution | Image name |
---|---|---|
iPhone 1g-3Gs | 320x480 | Default.png |
iPhone 4, 4s | 640x960 | Default@2x.png |
iPhone 5, 5c, 5s | 640x1136 | Default-568h@2x.png |
iPhone 6s - 8 | 750x1334 | Default-667h@2x.png |
iPhone 6s Plus - 8 Plus | 1242x2208 | Default-736h@3x.png |
iPhone X | 1125px × 2436px | Default-1125h.png |
iPhone X Landscape | 2436px × 1125px | Default-Landscape-X.png |
iPad, iPad 2, Mini | 768x1024 | Default-Portrait.png |
iPad Landscape | 1024x768 | Default-Landscape.png |
iPad Retina | 1536x2048 | Default-Portrait@2x.png |
12.9" iPad Pro | 2048x1536 | Default-Landscape@2x.png |
Note
For a better understanding of the supported image resolutions for the different iOS devices, refer to iOS Human Interface Guidelines or check our reference table.
Drag and drop your Assets.xcassets into Xcode (7.1 or newer version). In the opened window add the proper image for each iOS version and device. Close Xcode and rebuild your NativeScript app to use the new launch images.
Important
Make sure you have provided all required images or your app will be rejected from publishing in the App Store.
The default template app in NativeScript comes with LaunchScreen.storyboard, which contains two image views. The first one, named LaunchScreen.AspectFill.imageset, is used to visualize your background. The second one, named LaunchScreen.Center.imageset, is used to visualize your centered logo. Your own storyboard can be customized to use your own logic with different images and styles. However, keep in mind that according to iOS Human Interface Guidelines, the LaunchScreen should be as light as possible with minimal or no moving elements and text labels. It is meant to provide immediate UX rather than artistic presentation.
Open LaunchScreen.AspectFill.imageset and change the default LaunchScreen.AspectFill images with your own using the proper scale for each image (1x, 2x and 3x). As this is an image that will be used in your LaunchScreen.storyboard, your actual resolution may vary depending on your design. The default NativeScript template ships a LaunchScreen-AspectFill.png and LaunchScreen-AspectFill@2x.png used as a sample background. If your images have different file names then open Contents.json and change the key filename
for each image.
Important
After each file change in the Assets.xcassets folder you should rebuild your project and restart your emulator to avoid visualizing cached images.
Drag and drop your Assets.xcassets into Xcode (7.1 or newer version). In the opened window choose LaunchScreen.AspectFill and add the properly scaled image for each entry (1x, 2x and 3x). Close Xcode and rebuild your NativeScript app to use the new LaunchScreen.AspectFill.
Open LaunchScreen.Center.imageset and change the default LaunchScreen.Center images with your own using the proper scale for each image (1x, 2x and 3x). As this is an image that will be used in your LaunchScreen.storyboard, your actual resolution may vary depending on your design. The default NativeScript template ships a LaunchScreen-Center.png and LaunchScreen-Center@2x.png used as a sample center logo image. If your images have different file names then open Contents.json and change the key filename
for each image.
Important
After each file change in the Assets.xcassets folder you should rebuild your project and restart your emulator to avoid visualizing cached images.
Drag and drop your Assets.xcassets into Xcode (7.1 or newer version). In the opened window choose LaunchScreen.Center and add the properly scaled image for each entry (1x, 2x and 3x). Close Xcode and rebuild your NativeScript app to use the new LaunchScreen.Center.
Certificates, identifiers and profiles are managed at https://developer.apple.com/membercenter.
You should really explore the information Apple provides on certificates and identities. This article will cover only the basics.
You will need a developer account with an Apple ID so you can access the Apple Developer Member Center.
You will need to be added as an iOS developer in your organization.
Development certificates are used to sign iOS apps proving the origin of the app. If you plan to use the Xcode tooling it would be best to create a development certificate.
A few pitfalls are:
Note
Go to https://developer.apple.com/account/ios/certificate/certificateList.action?type=development click the '+' (add) button and follow the instructions for making a new 'iOS App Development' certificate.
Production certificates work similarly to development certificates. They consist of public and private keys. The private key stays at your side and is never sent to Apple. Your app is signed with the distribution certificate using your private key, so Apple can verify the origin of submissions in iTunes Connect using the public key you sent them.
This production certificates is used to sign the application binary when it is prepared for submission. Usually when an app is built for a device, its IPA file is signed with the development certificate.
Note
You can read more about IPA (file extension) here Later, the tooling resigns the IPA with the production certificate and appends the distribution provisioning profile when submitting to iTunes Connect.
A few pitfalls are:
If you need a new distribution certificate, go to https://developer.apple.com/account/ios/certificate/certificateList.action?type=distribution click the '+' (add) button and follow the instructions for making a new 'App Store Distribution' certificate. Chances are you are part of a larger organization and your role does not have sufficient rights to create a new distribution certificate. Admins or other team member may provide you the certificates in that case. In such cases, you will probably be given a .p12 file and a password. You should import the file in your keychain using the Keychain Access
application.
To test your app on a device or submit in the App Store, you will need to create an App ID. App IDs consist of a Prefix or a Team ID that is generated by Apple, followed by an ID provided by you that must match your Bundle ID. For example, you can create an App ID with the org.nativescript.*
ID that will match all your NativeScript apps. The wildcard pattern imposes some restrictions on the services you can use, so you may also consider using a non-wildcard pattern such as org.nativescript.<my-app>
.
These identifiers are later used to bind apps with provisioning profiles.
At the Member Center you can register the devices you and your team use for testing. Go to https://developer.apple.com/account/ios/device/deviceList.action.
To register a phone you will need its UDID. Connect it to the Mac and run in a terminal:
instruments -s devices
It will output all known devices and their UDIDs.
Development provisioning profiles bind together one or multiple developer signing identities (developer certificates), App ID and device IDs. These are created at https://developer.apple.com/account/ios/profile/profileList.action?type=limited. If you are making a new one, or adding a new app to an existing one, make sure to select these three:
Unlike the certificates, provisioning profiles are files that can be easily updated and downloaded from the Member Center (in .mobileprovision files) and installed in Xcode by double-clicking that file.
Xcode is also capable of obtaining these automatically. Open Xcode and from the menu go to Xcode > Preferences... > Accounts > (select your apple ID) > (double-click on your Team Name)
. There you can check all signing identities (developer and production certificates) available to Xcode as well as Download All
provisioning profiles.
When you run an app on a device, Xcode will sign the app with your development certificate and add a provisioning profile that has your certificate, device ID and App ID.
While the development provisioning profiles are easily created and updated, they frequently invalidate, especially when multiple developer certificates are involved. Every time one of them is revoked or expires, you need to update the provisioning certificate.
These are not of a particular interest for App Store submissions but you may need one to test on a real device.
There are several distribution provisioning profile types. The one you will need for App Store submission is 'App Store Distribution Provisioning Profile'. These are similar to the development provisioning profiles because they bind:
Distribution provisioning profiles are created at https://developer.apple.com/account/ios/profile/profileList.action?type=production.
For App Store submissions, you must create an App Store Distribution Provisioning Profile. Once you create it, download it and double-click it on your Mac so it gets registered with Xcode.
Distribution provisioning profiles invalidate rarely since they refer a single Distribution Certificate.
While you manage your provisioning profiles and certificates at the Apple Developer Member Center, apps are registered and submitted at App Store Connect (former iTunes Connect). This is where you will be able to create new apps, prepare app screens, descriptions, manage app versions, etc.
You will need your Apple ID added to your organization with sufficient rights at https://appstoreconnect.apple.com.
To publish your app in the iOS App Store you will have to register your app. Log into https://appstoreconnect.apple.com and go to 'My Apps'. There you can check the status and edit existing apps or create a new app.
Click the '+' button at the top left corner. The 'New App' dialog should appear. There you have to fill the public App Store name of your app and primary language.
Also, you have to set Bundle ID, which must match the Bundle ID referred in '1.1. Bundle ID'. If the drop-down does not contain a suitable match, you are probably missing an App ID referred at '2.4. Identifiers - App IDs'. If there is a wildcard App ID, that is a potential match so select it. You will be able to type the suffix, replacing the wildcard in a text box.
At that point you have to fill in the App Information. There are various assets that you must provide such as screenshots, icons, description, etc. Failing to provide all necessary assets may prevent you from submitting your app, or result in app rejection.
Note
Screenshots not matching the actual app may result in rejection of a new version sent for approval.
Once you have your app information registered at https://appstoreconnect.apple.com it is time to build your NativeScript app for iOS and submit it to iTunes Connect — using Xcode.
We have already explained how the Bundle ID is set in your project, how the launch screen (or storyboard) and images are added to your app, and how you can set the display name.
Before the build, you need to set two important things: the Bundle Short Version String and the Bundle Version String.
Bundle Short Version String is the public version of your app. It is incremented between releases. For example: 2.1
. Bundle Version String is the internal build number. One public release usually has multiple release candidates. For example 2.1.1
, 2.1.2
, etc.
iTunes Connect has a restriction that a bundle cannot be uploaded with the same version twice, so you must increment the Bundle Version String with each upload.
The Bundle Short Version String should be incremented once your app version is uploaded, sent for approval, approved and published.
Both values are stored in app/App_Resources/iOS/Info.plist
:
CFBundleShortVersionString
key stores the Bundle Short Version String.CFBundleVersion
key stores the Bundle Version String.In the app/App_Resources/iOS/Info.plist
they appear as:
<key>CFBundleShortVersionString</key>
<string>2.1</string>
<key>CFBundleVersion</key>
<string>2.1.2</string>
If you need to edit these from the command line, there is a handy tool called PlistBuddy
that can read and write Plist files. For example, the following shell script appends the Jenkins $BUILD_NUMBER
to the CFBundleVersion
in the Info.plist:
### Set CFBundleVersion ###
export CFBundleVersion=`/usr/libexec/PlistBuddy app/App_Resources/iOS/Info.plist -c "Print :CFBundleVersion"`
/usr/libexec/PlistBuddy app/App_Resources/iOS/Info.plist -c "Set :CFBundleVersion $CFBundleVersion.$BUILD_NUMBER"
You can execute the following command inside a NativeScript project using the CLI:
ns publish ios
The command will prompt for your Apple ID
and Password
for authentication with iTunes Connect and then produce a release
build and proceed to upload it to iTunes Connect.
Alternatively, you can use an existing build by running the following command:
ns publish ios --ipa <path-to-ipa>
For more information, run the following command:
ns help publish ios
You can execute the following command using the CLI:
ns prepare ios
This will create an Xcode project in platforms/ios/
. Then you may consider the following Apple article about how to configure the project for distribution.
The platform
folder is not meant to stay in source control and you should be careful when you do modifications there. Rebuilds may erase your changes and you should add changed files to source control.
A common pitfall, if you are using CocoaPods, is to open the Xcode project instead of the workspace, so be sure to open the workspace.
Once you have it open in Xcode, you have to go to your target's Signing & Capabilities
and pick a team. In Build Settings
there should be a suitable 'iOS Developer' and 'Code Signing Identity'.
From the top drop-down, select your target, and from the devices and emulators, pick 'Generic iOS Device'.
Then you should be able to select from the top menu Product > Archive
.
This makes an xcodearchive and opens it in the Xcode Organizer. The Xcode Organizer displays a list with builds of your app. Pick the last build and click Upload to App Store...
. You should select a team again and whether to include app symbols for your app. Next, you can see a list with the binary information, entitlements, etc. Click Upload
.
If you upload successfully, you should be able to log in at https://appstoreconnect.apple.com and see your build in 'Activities'. From there you can enable Test Flight beta testing or send it for approval.
Automation can be achieved using the NativeScript CLI only. All of the parameters needed for publishing can be passed to the publish
command directly:
ns publish ios [<Apple ID> [<Password> [<Mobile Provisioning Profile Identifier> [<Code Sign Identity>]]]]]
For example, assuming that you want to issue a build using a mobile provision with an identifier d5d40f61-b303-4fc8-aea3-fbb229a8171c, you could run:
ns publish ios my-apple-id my-password d5d40f61-b303-4fc8-aea3-fbb229a8171c "iPhone Distribution"
Note that the Code Sign Identity
can be set to something generic like iPhone Distribution in order to let the build automatically detect a code sign identity.
You can also automate the uploads of already built packages:
ns publish ios my-apple-id my-password --ipa /tmp/build/myIpa.ipa
Some tools that allow the submission process to be automated - MIT Licensed one: fastlane.
Once you successfully submit a build at App Store Connect, you can enable testing through Test Flight. When you are ready, go to the 'Build' section of your iOS app, pick the build, and click 'Submit for Review' for that version. The app will pass through several App Statuses. If your app passes Apple review, it can go live at the App Store.