Create a Plugin to Display Animated Gif in a NativeScript Image
One of the many great things about NativeScript, is the ability to access the native capabilities of the platforms without any border. The entire ecosystem, the CocaPods for iOS and the gradle pluging for Android are no exception and can be used seamlessly in your application. You can also easily create abstraction layers separating the platform specific code from your logic manipulating it. With Angular on top of this, we can get an even cleaner result.
In this post, I’ll show you how to create an (Angular) plugin for displaying animated gifs on a normal NativeScript Image layout. Since none of the two platforms have an out-of-the-box way to play an animated gif, we’ll use native plugins (CocoaPod and Gradle).
Setting up the Plugin
We’ll start by creating the Angular plugin. We’re going to create it from scratch in order for you to understand the different step, and also to use only what we’ll need for the real application. If you want to start from an existing base and if you need more complex dependencies, I recommend that you check out Nathan Walker‘s nativescript-ngx-plugin-seed.
Let’s start by creating the plugin’s directory. We’ll name it tns-ng-gif, as the name of our plugin:
The plugin is going to be an npm package, so let’s run
npm init to create the package.json file, or create it manually. Make sure it has a similar content as:
Note the “nativescript” key, with the two platform declarations. This is necessary to indicate that this is a NativeScript plugin and it can be imported into an application.
The next step is to add the packages needed for the plugin. Start by installing the normal dependencies:
Then go ahead and install the development dependencies:
Let’s now modify the package.json to add the build script, which will simply be a tsc command call:
We’re now ready to write the code of our plugin.
Install the native Dependencies
We need to find the native dependencies suiting our needs. For iOS, we can search through the CocoaPods and choose the one we want to use. The AnimatedGif one seem so be a good match. To use it within the plugin, we simply have it to reference it in a Podfile, as you would normally do in a iOS codebase. The latter needs to be hosted in a platforms/ios folder within the plugin:
For Android, we’re going to use the Glide which is very easy to use. Let’s create an include.gradle file in platforms/android, and reference the plugin in it:
Create the GifDirective
As mentioned before, we want to use an existing Image layout in order to display a gif inside it. The Angular way to do it is to use a Directive.
Let’s start with the iOS implementation:
Create the iOS Directive
We’ll start with the iOS implementation of the directive. The NativeScript runtime uses the file extension to differentiate between the platforms implementations. If the file is ending with .ios.js, (.ios.ts at design time) it’ll be executed on iOS exclusively and .android.js, on Android. With that in mind, let’s create our GifDirective for iOS:
Now, we can write the implementation, using the Pod we referenced earlier.
According to the Pod’s documentation, one example of use would be the following (in Objective-C):
Which we can translate in NativeScript code and come up with the following Directive:
The Image layout already has a src property, so we’re reusing it to access the gif file we want to set.
Let’s move on to the Android implementation.
Create the Android Directive
Create a new gif.directive.android.ts file in the gif directory, with the following content:
By looking at the two files, we notice something common needed by the native implementations: they both need the Image, as well as the gif absolute path in input. Let’s isolate the platform specific code in two different files, exposing the same function, that we’ll call toGif:
Then, create the type definition in order to import the function in a platform agnostic way:
This allows us to create a unique version of the Directive, and delete the platform specific ones:
Create the Plugin’s NgModule
Let’s wrap the directive into a NgModule representing our plugin. The consuming application will simply have to import it in order to the Directive in any of its components. Go ahead and create a new file called tns-ng-gif.ts (the same name as the ‘main’ defined in the package.json):
That’s pretty much it for the plugin. We can now build it using:
To use it within a NativeScript Angular application, add it using:
Then, import the GifModule into the module where you want to display a gif:
And finally, you can use the Directive in a Template inside your module to a normal Image layout:
Which of course display the expected result, on both platforms 🙂 :
I hope this post has been useful to you and if it’s the case, go ahead and share it. Don’t hesitate to write a comment if you encounter any trouble along the way, or if you notice a potential enhancement!
EDIT: I’ve created a npm package out of this post, check it out here.Angular2, NativeScript, TypeScript and tagged android, angular, gif, IOS, nativescript, plugin. Bookmark the permalink.