Skip to content

Instantly share code, notes, and snippets.

@debojyoti
Last active October 31, 2019 10:02
Show Gist options
  • Save debojyoti/489b6e940afe1a9bad04979465c28166 to your computer and use it in GitHub Desktop.
Save debojyoti/489b6e940afe1a9bad04979465c28166 to your computer and use it in GitHub Desktop.

Terms and conditions of cross-platform frameworks

Single codebase

Nowadays cross-platform (CP) mobile app development is on the eye of everyone. Enterprises are almost forced to take CP frameworks into consideration when planning a new prdouct/service or update to an older one. Also, developers having CP skills are totally in-demand. Let’s get a little context and analyze this phenomena.

Development options available

In the mobile realm, you’ll hear often terms like native app and hybrid app. What’s the difference?

Native application built using software development tools (SDK) for a certain software framework, hardware platform or operating system. Like Android app built using Java Development Kit on Java platform, iOS app built using iOS SDK, Swift and Objective C. Similarly, .NET required for Windows platform.

Whereas Hybrid applications are essentially a combination of native apps and web apps. Mostly hybrid apps shares the same codebase used for web, which is one of the major advantages as it cuts down the development time and cost as well.

Why hybrid?

With competition burgeoning in digital market every day, it is important to leverage the process that offers greater speed and lower cost of mobile app development. Hybrid mobile apps not only resolves the problem of targeting each platform with separate native apps but also helps find quickest spot in online app store market. Also, hybrid apps have integrated backend and some functionality of native apps, combining the best of both.

Meet IONIC

Single codebase

Ionic is one of the most popular framework to build high-performance hybrid applications that look and feel beautiful on multiple platforms and devices. It majorly uses mobile-optimized components built with popular web technologies (Angular/Vue/React). It comes with very native-styled mobile UI elements and layouts that you’d get with a native SDK on iOS or Android but didn’t really exist before on the web.

Advantages of using IONIC

  • Can adapt codebase written with popular JavaScript frameworks (Angular/Vue/React)
  • IONIC provides a set of readymade components with platform specific flavors.
  • Most of the native plugins of IONIC are built on the top of cordova's core plugins, which almost doubles the support community.
  • Cordova also provides all the functionality found in native mobile development SDKs including all major hardware access support (camera, gps, networks etc)

Platform independent codebase - not at all

Though hybrid sdk uses single codebase for all platforms, still platform specific tweaks are required in some cases in order to maintain similar behaviour across all supported platforms. The cases are very random, for example tweaks can be required while integrating a 3rd party plugin. It may even required for some native plugins as well. The solutions are not always available in their documentation. In most of the cases we need to apply custom patches. And the combined support of IONIC and cordova community also comes into play here. For example here are some cases I faced recently and configured the projects with tweaks.

#1 Header issue in IOS

This is one of the issues that exists within ionic UI native components. In the iOS build the header area is always covered by an invisible status bar. So any clickable ui elements (eg: Hamburger menu, navigation buttons) in the header portion get very less clickable area.

The highlighted area represents the invisible status bar

It can be easily solved by a simple tweak in project's config.xml file. Just need to add

<platform name="ios">
    <custom-config-file parent="UIStatusBarHidden" platform="ios" target="*-Info.plist">
        <true />
    </custom-config-file>
    <custom-config-file parent="UIViewControllerBasedStatusBarAppearance" platform="ios" target="*-Info.plist">
        <false />
    </custom-config-file>
</platform>

#2 Custom tweaks for a 3rd party plugin

Lot of 3rd party plugins require platform specific customiztions. For example Instabug (A bug reporting plugin) which is a very good tool to trace user's feedback in realtime and help teams to debug faster. Now this works poperly in iOS but for android some modifications are required in platform files

After adding android platform

  1. Find the application tag in platforms/android/AndroidManifest.xml file and add the android:name attribute value with com.instabug.cordova.plugin.MyApplication
<application 
    android:hardwareAccelerated="true" 
    android:icon="@mipmap/icon" 
    android:label="@string/app_name" 
    android:name="com.instabug.cordova.plugin.MyApplication" 
    android:supportsRtl="true">
  1. Need to add the API key to the MyApplication file located at platforms/android/src/com/instabug/cordova/plugin/MyApplication.java
new Instabug.Builder(
        this,
        "INSTABUG_TOKEN",
        InstabugInvocationEvent.SHAKE
).build();
  1. multiDexEnabled should be enabled in build.gradle located at platforms/android/
android {
    sourceSets {
        main {
            ...
        }
    }

    defaultConfig {
        ...
        multiDexEnabled true 
        ...
    }

#3 Directory structure dependency on platform

To let users store/download files from the app, the relative directory structure required to be set seperately for different platforms.

if (platform.is('ios')) {
    this.appDirectory = file.documentsDirectory;
  } else if (platform.is('android')) {
    this.appDirectory = file.externalDataDirectory;
  }

Similarly while using camera plugin, the destinationType should be FILE_URI for ios and NATIVE_URI for android in the cameraOptions.

const options: CameraOptions = {
  ...
  destinationType: this.platform.is('ios') ? this.camera.DestinationType.FILE_URI : this.camera.DestinationType.NATIVE_URI,
  ...
};
this.camera.getPicture(options).then((imageURI) => {
  ...
});

IONIC doc reference

#4 Contact list data inconsistency

This is an another issue with IONIC native plugin - Contact. To get the display name of imported contacts In iOS contact.name.givenName is used. Whereas in android contact.displayName is used to get the same property.

this.listOfContacts.forEach((contact) => {
       if (this.platform.is('ios')) {
         contact.displayName = contact.name.givenName;
       }
        //  else keep it same for android contact.displayName    
     });

Best Practices

Being a developer, I would suggest before you jump into the framework, you must try to adopt the best practices of that particular framework. This will not only improve the quality of your code but will also reduce your burden to maintain it. I have been working on Ionic framework for quite a long time and I feel following the rules written below will certainly help you to code in a better and cleaner way.

Properly document your codebase

"Documentation is a love letter that you write to your future self" - Damian Conway

Most of the developers just skip this part for speeding up the feature implementation but a successful product spends most of the time in maintenance phase of their lifecycle and why should we unnecessarily use our brain to keep what we did and how we did. So proper documentation can overcome from this problem, not to only make our codebase easily readable to the other devs but also we can also easily modify or maintain in future and also maintain the proper naming convention, so your naming methodology will solve half of the documantation process at the time when you write code.

Maintain Modular structure

It is always good practice to break a single page into multiple components where each and every component does their respective task. There are lot of benifits from developer prosepective

  • Reduce number of lines for each and every ts file which is easily maintainable and it creates your code clean
  • All the business logic has to be written in the service file, component just fetch the service file to get the data and modify it according to the user's demand.

Component has one entry and exit point and write it in correct order

Our code should be our friend, don't mess with your friend and make your life hell - this is I understood through my coding journey. Ionic has multiple entry points, before starting code in Ionic you have to know what are the purposes of different entry points and exit points. Always try to maintain one entry and one exit point. If your code demands multiple entry or exit points then write them in correct order according to the Ionic lifecycle hooks. Suppose you have an API endpoint using that you'll get all the page related data, so it will good practice to keep that call in constructor, it will reduce the loader icon appearance time.

Authors: Pritam Guha , Debojyoti Saha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment