And what’s in there actually?
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
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
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.
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
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.
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.
Make sure the Xcode IDE is the active window, and from the top menu, choose Debug >> View Debugging >> 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.
(click the picture to enlarge it)
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
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.
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.
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. :)