How to analyze the app package and native visual UI tree of a NativeScript application


And what’s in there actually?

Applications written with web means such as JavaScript and CSS are usually taken as web or hybrid. With NativeScript we enable these web ​skills allowing you to write in your favorite language (JavaScript or TypeScript - the choice is yours) achieving great, fast-performing native apps. But, in the dawn of NativeScript and even now when it’s v1, we have been encountering non-believers who wonder “Are the NativeScript apps real native apps as they execute on the device? Or, they are hybrid after all :)”

With this blog post I would like to reveal the truth for the non-believers by dissecting a NativeScript app at runtime and displaying what UI elements are actually created and executed on iOS and Android. Well, I can tell you from now - ​these objects are the native UI components of the respective platform. But if you still don’t believe me, read on.

I don’t want to display too complex graphs of objects, but just to present the general idea, so for this purpose I am going to dissect the sample Photo Album app from our Quick Start tutorial. I slightly changed the Photo Album repo to load two images by default instead of taking them from the camera, so that we can see right away how the images are represented in each platform.

The native app packages

iOS

If you run the app on the simulator or just build it, this will create an *.app file and the full path to it will look like:

Photo Album Native Code\platforms\ios\build\emulator\PhotoAlbumNativeCode.app.

This is the application file that is created when you build the app. 

Right-click it, choose Show Package Contents and you will be able to view the contents of your application. As you can ​notice there, you can view the JavaScript, CSS and XML files, as well the actual executable file of the project (hidden in metadata-armv7.bin) that uses the JS, CSS and XML files.

ios-show-package-contents

Let’s say that we want to run the app on a device. In this case, an *.ipa file is created and is then deployed and executed on the device. The *.ipa file is created at:

Photo Album Native Code\platforms\ios\build\device\PhotoAlbumNativeCode.ipa

Right-click the ipa file and choose Open With >> Archive Utility. This will create a Payload folder that contains the app file discussed earlier.

ios-device-archive-utility

Android

Building or running our Android project creates an *.apk application file at:

Photo Album Native Code\platforms\android\bin\PhotoAlbumNativeCode-debug.apk

Let’s see what’s in there. We can open it with any archiver as, in its essence, an *.apk file is a zip file. So, there, in the assets\app folder of the apk archive we have the JavaScript, XML and CSS file(s) that we implemented to create the app, a few NativeScript service files, and a dex file that uses the JS, XML and CSS to run the app.

android-contents

The native visual tree of runtime objects

We just saw that it’s JS, CSS and XML that is contained in the application packages. Based on the repo, we also know that we have a GridLayout with a ListView and a Button, where the ListView contains two images wrapped in GridLayouts. Let’s see now to what these are transformed at runtime. 

iOS

emulator-ios

Go to Photo Album Native Code\platforms\ios and open the PhotoAlbumNativeCode.xcodeproj file that you will find there. This is the Xcode project representation of our NativeScript application and this project is compiled as you build the NativeScript app. We will now use one of the Xcode tools to inspect the hierarchy of objects at runtime. 

With the Xcode project opened, run the app using the Play button of Xcode, specifying the Simulator device model. Let’s say it is iPhone 6.

xcode-play

Make sure the Xcode IDE is the active window, and from the top menu, choose Debug >> View Debugging >> Capture View Hierarchy .

ios-capture-view-hierarchy

Voila! The application runtime object structure is revealed and… as you can see it’s all a hierarchy of native iOS objects. Starting from the UILayoutContainerView and UINavigationTransitionView (being there because by default we include a UINavigationController), going down through the UITableView used for the ListView wrapper, continuing with the UIImageViews used to show the images. Of course, at the bottom there are the UIButton with the UIButtonLabel representing the NativeScript Button.

ios-hierarchy
(click the picture to enlarge it)

Android

In order to inspect the hierarchy of native elements, we can use a standalone tool called monitor that is a part of the Android SDK. Usually, you can find it at your [Android SDK Folder]\tools\monitor.

android-emulator 

Supposing that we have run the app with tns run android --emulator and we have the running application in place, open the monitor app and from the left-side panel select the NativeScriptActivity which will show the hierarchy view of the native objects that the NativeScript application has. 

android-monitor-choose-activity

As you can see below, we have only objects native to the Android platform - Android ListView for the NativeScript ListView, Android Button for the NativeScript Button, Android ImageView for the NativeScript Image. There are also objects for the navigation control on the top. 

android-monitor-hierarchy

So, there you have it - the proof that it’s an app of native objects that is executed on the device - no hybrid stuff or WebViews whatsoever. The next time somebody comes to you with “These NativeScript guys, they make a hybrid thing”, show them this blog, they’ll be amazed. :)

Comments


Comments are disabled in preview mode.
NativeScript is licensed under the Apache 2.0 license
© 2020 All Rights Reserved.