Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon

How-To Tutorials - Android Programming

62 Articles
article-image-a-decade-of-android-slayer-of-blackberry-challenger-of-iphone-mother-of-the-modern-mobile-ecosystem
Sandesh Deshpande
06 Oct 2018
6 min read
Save for later

A decade of Android: Slayer of Blackberry, challenger of iPhone, mother of the modern mobile ecosystem

Sandesh Deshpande
06 Oct 2018
6 min read
If someone says Eclair, Honeycomb, Ice Cream Sandwich, or Jelly Bean then apart from getting a sugar rush, you will probably think of Android OS. From just being a newly launched OS, filled with apprehensions, to being the biggest and most loved operating system in the history, Android has seen it all. The OS which powers our phones and makes our everyday life simpler recently celebrated its 10th anniversary. Android’s rise from the ashes The journey to become the most popular mobile OS since its launch in 2008, was not that easy for Android. Back then it competed with iOS and Blackberry, which were considered the go-to smartphones of that time. Google’s idea was to give users a Blackberry-like experience as the 'G1' had a full-sized physical Qwerty keypad just like Blackberry. But G1 had some limitations as it could play videos only on YouTube as it didn’t have any inbuilt video player app and Android Market (now Google Play) and had just a handful of apps. Though the idea to give users blackberry like the experience was spot on, it was not a hit with the users as by then Apple had made touchscreen all the rage with its iPhone. But one thing Google did right with Android OS, which its competitors didn't offer, was customizations and that's where Google scored a home run. Blackberry and iPhone were great and users loved them. But both the OS tied the users in their ecosystem. Motorola saw the potential for customization and it adopted Android to launch Motorola Droid in 2009.  This is when Android OS came of age and started competing with Apple's iOS. With Android OS, people could customize their phones and with its open source platform developers could tweak the Base OS and customize it to their liking. This resulted in users having options to choose themes, wallpapers, and launchers. This change pioneered the requirement for customization which was later adopted in iPhone as well. By virtue of it being an open platform and thanks to regular updates from Google, there was a huge surge in Android adoption and mobile manufacturers like Motorola, HTC, and Samsung launched their devices powered by Android OS. Because of this rapid adoption of Android by a large number of manufacturers, Android became the most popular mobile platform, beating Nokia's Symbian OS by the end of 2010. This Android phenomenon saved many manufacturers like HTC, Motorola, Samsung, Sony for losing significant market share to the then mobile handset market leaders, Nokia, Blackberry and Apple. They sensed the change in user preferences and adopted Android OS. Nokia, on the other hand, didn’t adopt Android and stuck to it’s Symbian OS which resulted in customer and market loss. Android: Sugar, and spice and everything nice In the subsequent years, Google launched Android versions like Cupcake, Donut, Eclair, Froyo, Gingerbread, Ice cream Sandwich, Jelly Bean, KitKat, Lollipop, and Marshmallow. The Android team sure love their sugars evident from all Android operating systems named after desserts. It's not new that tech companies get unique names for their software versions. For instance,  Apple names its OS after cats like Tiger, Leopard and Snow Leopard. But Google officially never revealed why their OS is named after desserts. Just in case that wasn't nerdy enough, Google put these sugary names in alphabetical order. Each update came with some cool features. Here’s a quick list of some popular features with the respective versions. Eclair (2009): Phone which came with Eclair onboard had digital zoom and flashlight for photos for the first time ever. Honeycomb (2011): Honeycomb was compatible with a tablet without any major glitches. Ice cream Sandwich (2011): Probably not as sophisticated as today but Ice cream sandwich had facial recognition and also a feature to take screenshots. Lollipop (2014): With Android Lollipop rounded icons were introduced in Android for the first time. Nougat (2016): With Nougat update Google introduced more natural looking emojis including skin tone modifiers, Unicode 9 emojis, and a removal of previously gender-neutral characters. Pie (2018): The latest Android update Android Pie also comes  with a bunch of cool features. However, the standout feature in this release is the  Indoor navigation which enables indoor GPS style tracking by determining your location within a building and facilitating turn-by-turn directions to help you navigate indoors. Android’s greatest strength probably is its large open platform community which helps developers to develop apps for Android. Though developers can write Android apps in any Java virtual machine (JVM) compatible programming language and can run on JVM, Google’s primary language for writing Android apps was Java (besides C++). At Google I/O 2018, Google announced that it will officially support Kotlin on Android as a “first-class” language. Kotlin is a super new programming language built by JetBrains, which also coincidentally develops the JetBrains IDE that powers the Android Studio. Apart from rich features and strong open platform community, Google also enhanced security with the newer Android versions which made it unbeatable. Manufacturers like Samsung leveraged the power of Android with their Galaxy S series making them one of the leading mobile manufacturers. Today, Google have proven themselves as strong players in the mobile market not only with Android OS but also with their Flagship phones like the Pixel series which receive updates before any other Smartphone with Android OS. Android today: love it, hate it, but you can’t escape it Today with a staggering 2 Billion active devices, Android is the market leader in mobile OS platform by far. A decade ago, no one anticipated that one mobile OS could have such dominance. Google has developed the OS for televisions, smartwatches, smart home devices, VR Headsets and has even developed Android Auto for cars. As Google showcased in Google I/O 2018 the power of machine learning with Smart compose for Gmail and Google Duplex for Google assistant, with Google assistant now being introduced on almost all latest android phones it is making Android more powerful than ever. However, all is not all sunshine and rainbows in the Android nation. In July this year, EU slapped Google with $5 billion fine as an outcome of its antitrust investigations around Android. Google was found guilty of imposing illegal restrictions on Android device manufacturers and network operators, since 2011, in an attempt to get all the traffic from these devices to the Google search engine. It is ironic that the very restrictive locked-in ecosystems that Android rebelled against in its early days are something it is now increasingly endorsing. Furthermore, as interfaces become less text and screen-based and more touch, voice, and gesture-based, Google does seem to realize Android’s limitations to some extent. They have been investing a lot into Project Fuschia lately, which many believe could be Android’s replacement in the future. With the tech landscape changing more rapidly than ever it will be interesting to see what the future holds for Android but for now, Android is here to stay. 6 common challenges faced by Android App developers Entry level phones to taste the Go edition of the Android 9.0 Pie version Android 9 pie’s Smart Linkify: How Android’s new machine learning based feature works
Read more
  • 0
  • 0
  • 4069

article-image-restful-web-services-with-kotlin
Natasha Mathur
01 Jun 2018
9 min read
Save for later

Building RESTful web services with Kotlin

Natasha Mathur
01 Jun 2018
9 min read
Kotlin has been eating up the Java world. It has already become a hit in the Android Ecosystem which was dominated by Java and is welcomed with open arms. Kotlin is not limited to Android development and can be used to develop server-side and client-side web applications as well. Kotlin is 100% compatible with the JVM so you can use any existing frameworks such as Spring Boot, Vert.x, or JSF for writing Java applications. In this tutorial, we will learn how to implement RESTful web services using Kotlin. This article is an excerpt from the book 'Kotlin Programming Cookbook', written by, Aanand Shekhar Roy and Rashi Karanpuria. Setting up dependencies for building RESTful services In this recipe, we will lay the foundation for developing the RESTful service. We will see how to set up dependencies and run our first SpringBoot web application. SpringBoot provides great support for Kotlin, which makes it easy to work with Kotlin. So let's get started. We will be using IntelliJ IDEA and Gradle build system. If you don't have that, you can get it from https://www.jetbrains.com/idea/. How to do it… Let's follow the given steps to set up the dependencies for building RESTful services: First, we will create a new project in IntelliJ IDE. We will be using the Gradle build system for maintaining dependency, so create a Gradle project: When you have created the project, just add the following lines to your build.gradle file. These lines of code contain spring-boot dependencies that we will need to develop the web app: buildscript { ext.kotlin_version = '1.1.60' // Required for Kotlin integration ext.spring_boot_version = '1.5.4.RELEASE' repositories { jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // Required for Kotlin integration classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version" // See https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin classpath "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version" } } apply plugin: 'kotlin' // Required for Kotlin integration apply plugin: "kotlin-spring" // See https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin apply plugin: 'org.springframework.boot' jar { baseName = 'gs-rest-service' version = '0.1.0' } sourceSets { main.java.srcDirs += 'src/main/kotlin' } repositories { jcenter() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" // Required for Kotlin integration compile 'org.springframework.boot:spring-boot-starter-web' testCompile('org.springframework.boot:spring-boot-starter-test') } Let's now create an App.kt file in the following directory hierarchy: It is important to keep the App.kt file in a package (we've used the college package). Otherwise, you will get an error that says the following: ** WARNING ** : Your ApplicationContext is unlikely to start due to a `@ComponentScan` of the default package. The reason for this error is that if you don't include a package declaration, it considers it a "default package," which is discouraged and avoided. Now, let's try to run the App.kt class. We will put the following code to test if it's running: @SpringBootApplication open class App { } fun main(args: Array<String>) { SpringApplication.run(App::class.java, *args) } Now run the project; if everything goes well, you will see output with the following line at the end: Started AppKt in 5.875 seconds (JVM running for 6.445) We now have our application running on our embedded Tomcat server. If you go to http://localhost:8080, you will see an error as follows: The preceding error is 404 error and the reason for that is we haven't told our application to do anything when a user is on the / path. Creating a REST controller In the previous recipe, we learned how to set up dependencies for creating RESTful services. Finally, we launched our backend on the http://localhost:8080 endpoint but got 404 error as our application wasn't configured to handle requests at that path (/). We will start from that point and learn how to create a REST controller. Let's get started! We will be using IntelliJ IDE for coding purposes. For setting up of the environment, refer to the previous recipe. You can also find the source in the repository at https://gitlab.com/aanandshekharroy/kotlin-webservices. How to do it… In this recipe, we will create a REST controller that will fetch us information about students in a college. We will be using an in-memory database using a list to keep things simple: Let's first create a Student class having a name and roll number properties: package college class Student() { lateinit var roll_number: String lateinit var name: String constructor( roll_number: String, name: String): this() { this.roll_number = roll_number this.name = name } } Next, we will create the StudentDatabase endpoint, which will act as a database for the application: @Component class StudentDatabase { private val students = mutableListOf<Student>() } Note that we have annotated the StudentDatabase class with @Component, which means its lifecycle will be controlled by Spring (because we want it to act as a database for our application). We also need a @PostConstruct annotation, because it's an in-memory database that is destroyed when the application closes. So we would like to have a filled database whenever the application launches. So we will create an init method, which will add a few items into the "database" at startup time: @PostConstruct private fun init() { students.add(Student("2013001","Aanand Shekhar Roy")) students.add(Student("2013165","Rashi Karanpuria")) } Now, we will create a few other methods that will help us deal with our database: getStudent: Gets the list of students present in our database: fun getStudents()=students addStudent: This method will add a student to our database: fun addStudent(student: Student): Boolean { students.add(student) return true } Now let's put this database to use. We will be creating a REST controller that will handle the request. We will create a StudentController and annotate it with @RestController. Using @RestController is simple, and it's the preferred method for creating MVC RESTful web services. Once created, we need to provide our database using Spring dependency injection, for which we will need the @Autowired annotation. Here's how our StudentController looks: @RestController class StudentController { @Autowired private lateinit var database: StudentDatabase } Now we will set our response to the / path. We will show the list of students in our database. For that, we will simply create a method that lists out students. We will need to annotate it with @RequestMapping and provide parameters such as path and request method (GET, POST, and such): @RequestMapping("", method = arrayOf(RequestMethod.GET)) fun students() = database.getStudents() This is what our controller looks like now. It is a simple REST controller: package college import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestMethod import org.springframework.web.bind.annotation.RestController @RestController class StudentController { @Autowired private lateinit var database: StudentDatabase @RequestMapping("", method = arrayOf(RequestMethod.GET)) fun students() = database.getStudents() } Now when you restart the server and go to http://localhost:8080, we will see the response as follows: As you can see, Spring is intelligent enough to provide the response in the JSON format, which makes it easy to design APIs. Now let's try to create another endpoint that will fetch a student's details from a roll number: @GetMapping("/student/{roll_number}") fun studentWithRollNumber( @PathVariable("roll_number") roll_number:String) = database.getStudentWithRollNumber(roll_number) Now, if you try the http://localhost:8080/student/2013001 endpoint, you will see the given output: {"roll_number":"2013001","name":"Aanand Shekhar Roy"} Next, we will try to add a student to the database. We will be doing it via the POST method: @RequestMapping("/add", method = arrayOf(RequestMethod.POST)) fun addStudent(@RequestBody student: Student) = if (database.addStudent(student)) student else throw Exception("Something went wrong") There's more… So far, our server has been dependent on IDE. We would definitely want to make it independent of an IDE. Thanks to Gradle, it is very easy to create a runnable JAR just with the following: ./gradlew clean bootRepackage The preceding command is platform independent and uses the Gradle build system to build the application. Now, you just need to type the mentioned command to run it: java -jar build/libs/gs-rest-service-0.1.0.jar You can then see the following output as before: Started AppKt in 4.858 seconds (JVM running for 5.548) This means your server is running successfully. Creating the Application class for Spring Boot The SpringApplication class is used to bootstrap our application. We've used it in the previous recipes; we will see how to create the Application class for Spring Boot in this recipe. We will be using IntelliJ IDE for coding purposes. To set up the environment, read previous recipes, especially the Setting up dependencies for building RESTful services recipe. How to do it… If you've used Spring Boot before, you must be familiar with using @Configuration, @EnableAutoConfiguration, and @ComponentScan in your main class. These were used so frequently that Spring Boot provides a convenient @SpringBootApplication alternative. The Spring Boot looks for the public static main method, and we will use a top-level function outside the Application class. If you noted, while setting up the dependencies, we used the kotlin-spring plugin, hence we don't need to make the Application class open. Here's an example of the Spring Boot application: package college import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication @SpringBootApplication class Application fun main(args: Array<String>) { SpringApplication.run(Application::class.java, *args) } The Spring Boot application executes the static run() method, which takes two parameters and starts a autoconfigured Tomcat web server when Spring application is started. When everything is set, you can start the application by executing the following command: ./gradlew bootRun If everything goes well, you will see the following output in the console: This is along with the last message—Started AppKt in xxx seconds. This means that your application is up and running. In order to run it as an independent server, you need to create a JAR and then you can execute as follows: ./gradlew clean bootRepackage Now, to run it, you just need to type the following command: java -jar build/libs/gs-rest-service-0.1.0.jar We learned how to set up dependencies for building RESTful services, creating a REST controller, and creating the application class for Spring boot. If you are interested in learning more about Kotlin then be sure to check out the 'Kotlin Programming Cookbook'. Build your first Android app with Kotlin 5 reasons to choose Kotlin over Java Getting started with Kotlin programming Forget C and Java. Learn Kotlin: the next universal programming language
Read more
  • 0
  • 0
  • 14578

article-image-integrate-firebase-android-ios-applications
Savia Lobo
28 May 2018
26 min read
Save for later

How to integrate Firebase on Android/iOS applications natively

Savia Lobo
28 May 2018
26 min read
In this tutorial, you'll see Firebase integration within a native context, basically over an iOS and Android application. You will also implement some of the basic, as well as advanced features, that are found in any modern mobile application in both, Android and iOS ecosystems. So let's get busy! This article is an excerpt taken from the book,' Firebase Cookbook', written by Houssem Yahiaoui. Implement the pushing and retrieving of data from Firebase Real-time Database We're going to start first with Android and see how we can manage this feature: First, head to your Android Studio project. Now that you have opened your project, let's move on to integrating the Real-time Database. In your project, head to the Menu bar, navigate to Tools | Firebase, and then select Realtime Database. Now click Save and retrieve data. Since we've already connected our Android application to Firebase, let's now add the Firebase Real-time Database dependencies locally by clicking on the Add the Realtime Database to your app button. This will give you a screen that looks like the following screenshot:  Figure 1: Android Studio  Firebase integration section Click on the Accept Changes button and the gradle will add these new dependencies to your gradle file and download and build the project. Now we've created this simple wish list application. It might not be the most visually pleasing but will serve us well in this experiment with TextEdit, a Button, and a ListView. So, in our experiment we want to do the following: Add a new wish to our wish list Firebase Database See the wishes underneath our ListView Let's start with adding that list of data to our Firebase. Now head to your MainActivity.java file of any other activity related to your project and add the following code: //[*] UI reference. EditText wishListText; Button addToWishList; ListView wishListview; // [*] Getting a reference to the Database Root. DatabaseReference fRootRef = FirebaseDatabase.getInstance().getReference(); //[*] Getting a reference to the wishes list. DatabaseReference wishesRef = fRootRef.child("wishes"); protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //[*] UI elements wishListText = (EditText) findViewById(R.id.wishListText); addToWishList = (Button) findViewById(R.id.addWishBtn); wishListview = (ListView) findViewById(R.id.wishsList); } @Override protected void onStart() { super.onStart(); //[*] Listening on Button click event addToWishList.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //[*] Getting the text from our EditText UI Element. String wish = wishListText.getText().toString(); //[*] Pushing the Data to our Database. wishesRef.push().setValue(wish); AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create(); alertDialog.setTitle("Success"); alertDialog.setMessage("wish was added to Firebase"); alertDialog.show(); } }); } In the preceding code, we're doing the following: Getting a reference to our UI elements Since everything in Firebase starts with a reference, we're grabbing ourselves a reference to the root element in our database We are getting another reference to the wishes child method from the root reference Over the OnCreate() method, we are binding all the UI-based references to the actual UI widgets Over the OnStart() method, we're doing the following: Listening to the button click event and grabbing the EditText content Using the wishesRef.push().setValue() method to push the content of the EditText automatically to Firebase, then we are displaying a simple AlertDialog as the UI preferences However, the preceding code is not going to work. This is strange since everything is well configured, but the problem here is that the Firebase Database is secured out of the box with authorization rules. So, head to Database | RULES and change the rules there, and then publish. After that is done, the result will look similar to the following screenshot:  Figure 2: Firebase Real-time Database authorization section After saving and launching the application, the pushed data result will look like this: Figure 3: Firebase Real-time Database after adding a new wish to the wishes collection Firebase creates the child element in case you didn't create it yourself. This is great because we can create and implement any data structure we want, however, we want. Next, let's see how we can retrieve the data we sent. Move back to your onStart() method and add the following code lines: wishesRef.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { //[*] Grabbing the data Snapshot String newWish = dataSnapshot.getValue(String.class); wishes.add(newWish); adapter.notifyDataSetChanged(); } @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) {} @Override public void onChildRemoved(DataSnapshot dataSnapshot) {} @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) {} @Override public void onCancelled(DatabaseError databaseError) {} }); Before you implement the preceding code, go to the onCreate() method and add the following line underneath the UI widget reference: //[*] Adding an adapter. adapter = new ArrayAdapter<String>(this, R.layout.support_simple_spinner_dropdown_item, wishes); //[*] Wiring the Adapter wishListview.setAdapter(adapter);  Preceding that, in the variable declaration, simply add the following declaration: ArrayList<String> wishes = new ArrayList<String>(); ArrayAdapter<String> adapter; So, in the preceding code, we're doing the following: Adding a new ArrayList and an adapter for ListView changes. We're wiring everything in the onCreate() method. Wiring an addChildEventListener() in the wishes Firebase reference. Grabbing the data snapshot from the Firebase Real-time Database that is going to be fired whenever we add a new wish, and then wiring the list adapter to notify the wishListview which is going to update our Listview content automatically. Congratulations! You've just wired and exploited the Real-time Database functionality and created your very own wishes tracker. Now, let's see how we can create our very own iOS wishes tracker application using nothing but Swift and Firebase: Head directly to and fire up Xcode, and let's open up the project, where we integrated Firebase. Let's work on the feature. Edit your Podfile and add the following line: pod 'Firebase/Database' This will download and install the Firebase Database dependencies locally, in your very own awesome wishes tracker application. There are two view controllers, one for the wishes table and the other one for adding a new wish to the wishes list, the following represents the main wishes list view.   Figure 4: iOS application wishes list view Once we click on the + sign button in the Header, we'll be navigated with a segueway to a new ViewModal, where we have a text field where we can add our new wish and a button to push it to our list.         Figure 5: Wishes iOS application, in new wish ViewModel Over  addNewWishesViewController.swift, which is the view controller for adding the new wish view, after adding the necessary UITextField, @IBOutlet and the button @IBAction, replace the autogenerated content with the following code lines: import UIKit import FirebaseDatabase class newWishViewController: UIViewController { @IBOutlet weak var wishText: UITextField //[*] Adding the Firebase Database Reference var ref: FIRDatabaseReference? override func viewDidLoad() { super.viewDidLoad() ref = FIRDatabase.database().reference() } @IBAction func addNewWish(_ sender: Any) { let newWish = wishText.text // [*] Getting the UITextField content. self.ref?.child("wishes").childByAutoId().setValue( newWish!) presentedViewController?.dismiss(animated: true, completion:nil) } } In the preceding code, besides the self-explanatory UI element code, we're doing the following: We're using the FIRDatabaseReference and creating a new Firebase reference, and we're initializing it with viewDidLoad(). Within the addNewWish IBAction (function), we're getting the text from the UITextField, calling for the "wishes" child, then we're calling childByAutoId(), which will create an automatic id for our data (consider it a push function, if you're coming from JavaScript). We're simply setting the value to whatever we're going to get from the TextField. Finally, we're dismissing the current ViewController and going back to the TableViewController which holds all our wishes. Implementing anonymous authentication Authentication is one of the most tricky, time-consuming and tedious tasks in any web application. and of course, maintaining the best practices while doing so is truly a hard job to maintain. For mobiles, it's even more complex, because if you're using any traditional application it will mean that you're going to create a REST endpoint, an endpoint that will take an email and password and return either a session or a token, or directly a user's profile information. In Firebase, things are a bit different and in this recipe, we're going to see how we can use anonymous authentication—we will explain that in a second. You might wonder, but why? The why is quite simple: to give users an anonymous temporal, to protect data and to give users an extra taste of your application's inner soul. So let's see how we can make that happen. How to do it... We will first see how we can implement anonymous authentication in Android: Fire up your Android Studio. Before doing anything, we need to get some dependencies first, speaking, of course, of the Firebase Auth library that can be downloaded by adding this line to the build.gradle file under the dependencies section: compile 'com.google.firebase:firebase-auth:11.0.2' Now simply Sync and you will be good to start adding Firebase Authentication logic. Let us see what we're going to get as a final result: Figure 6: Android application: anonymous login application A simple UI with a button and a TextView, where we put our user data after a successful authentication process. Here's the code for that simple UI: <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/ apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.hcodex.anonlogin.MainActivity"> <Button android:id="@+id/anonLoginBtn" android:layout_width="289dp" android:layout_height="50dp" android:text="Anounymous Login" android:layout_marginRight="8dp" app:layout_constraintRight_toRightOf="parent" android:layout_marginLeft="8dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginTop="47dp" android:onClick="anonLoginBtn" app:layout_constraintTop_toBottomOf= "@+id/textView2" app:layout_constraintHorizontal_bias="0.506" android:layout_marginStart="8dp" android:layout_marginEnd="8dp" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Firebase Anonymous Login" android:layout_marginLeft="8dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginRight="8dp" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="80dp" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Profile Data" android:layout_marginTop="64dp" app:layout_constraintTop_toBottomOf= "@+id/anonLoginBtn" android:layout_marginLeft="156dp" app:layout_constraintLeft_toLeftOf="parent" /> <TextView android:id="@+id/profileData" android:layout_width="349dp" android:layout_height="175dp" android:layout_marginBottom="28dp" android:layout_marginEnd="8dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.526" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf= "@+id/textView3" /> </android.support.constraint.ConstraintLayout> Now, let's see how we can wire up our Java code: //[*] Step 1 : Defining Logic variables. FirebaseAuth anonAuth; FirebaseAuth.AuthStateListener authStateListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); anonAuth = FirebaseAuth.getInstance(); setContentView(R.layout.activity_main); }; //[*] Step 2: Listening on the Login button click event. public void anonLoginBtn(View view) { anonAuth.signInAnonymously() .addOnCompleteListener( this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if(!task.isSuccessful()) { updateUI(null); } else { FirebaseUser fUser = anonAuth.getCurrentUser(); Log.d("FIRE", fUser.getUid()); updateUI(fUser); } }); } } //[*] Step 3 : Getting UI Reference private void updateUI(FirebaseUser user) { profileData = (TextView) findViewById( R.id.profileData); profileData.append("Anonymous Profile Id : n" + user.getUid()); } Now, let's see how we can implement anonymous authentication on iOS: What we'll achieve in this test is the following : Figure 7: iOS application, anonymous login application   Before doing anything, we need to download and install the Firebase authentication dependency first. Head directly over to your Podfile and the following line: pod 'Firebase/Auth' Then simply save the file, and on your terminal, type the following command: ~> pod install This will download the needed dependency and configure our application accordingly. Now create a simple UI with a button and after configuring your UI button IBAction reference, let's add the following code: @IBAction func connectAnon(_ sender: Any) { Auth.auth().signInAnonymously() { (user, error) in if let anon = user?.isAnonymous { print("i'm connected anonymously here's my id (user?.uid)") } } } How it works... Let's digest the preceding code: We're defining some basic logic variables; we're taking basically a TextView, where we'll append our results and define the Firebase  anonAuth variable. It's of FirebaseAuth type, which is the starting point for any authentication strategy that we might use. Over onCreate, we're initializing our Firebase reference and fixing our content view. We're going to authenticate our user by clicking a button bound with the anonLoginBtn() method. Within it, we're simply calling for the signInAnonymously() method, then if incomplete, we're testing if the authentication task is successful or not, else we're updating our TextEdit with the user information. We're using the updateUI method to simply update our TextField. Pretty simple steps. Now simply build and run your project and test your shiny new features. Implementing password authentication on iOS Email and password authentication is the most common way to authenticate anyone and it can be a major risk point if done wrong. Using Firebase will remove that risk and make you think of nothing but the UX that you will eventually provide to your users. In this recipe, we're going to see how you can do this on iOS. How to do it... Let's suppose you've created your awesome UI with all text fields and buttons and wired up the email and password IBOutlets and the IBAction login button. Let's see the code behind the awesome, quite simple password authentication process: import UIKit import Firebase import FirebaseAuth class EmailLoginViewController: UIViewController { @IBOutlet weak var emailField: UITextField! @IBOutlet weak var passwordField: UITextField! override func viewDidLoad() { super.viewDidLoad() } @IBAction func loginEmail(_ sender: Any) { if self.emailField.text</span> == "" || self.passwordField.text == "" { //[*] Prompt an Error let alertController = UIAlertController(title: "Error", message: "Please enter an email and password.", preferredStyle: .alert) let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil) alertController.addAction(defaultAction) self.present(alertController, animated: true, completion: nil) } else { FIRAuth.auth()?.signIn(withEmail: self.emailField.text!, password: self.passwordField.text!) { (user, error) in if error == nil { //[*] TODO: Navigate to Application Home Page. } else { //[*] Alert in case we've an error. let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert) let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil) alertController.addAction(defaultAction) self.present(alertController, animated: true, completion: nil) } } } } } How it works ... Let's digest the preceding code: We're simply adding some IBOutlets and adding the IBAction login button. Over the loginEmail function, we're doing two things: If the user didn't provide any email/password, we're going to prompt them with an error alert indicating the necessity of having both fields. We're simply calling for the FIRAuth.auth().singIn() function, which in this case takes an Email and a Password. Then we're testing if we have any errors. Then, and only then, we might navigate to the app home screen or do anything else we want. We prompt them again with the Authentication Error message. And as simple as that, we're done. The User object will be transported, as well, so you may do any additional processing to the name, email, and much more. Implementing password authentication on Android To make things easier in terms of Android, we're going to use the awesome Firebase Auth UI. Using the Firebase Auth UI will save a lot of hassle when it comes to building the actual user interface and handling the different intent calls between the application activities. Let's see how we can integrate and use it for our needs. Let's start first by configuring our project and downloading all the necessary dependencies. Head to your build.gradle file and copy/paste the following entry: compile 'com.firebaseui:firebase-ui-auth:3.0.0' Now, simply sync and you will be good to start. How to do it... Now, let's see how we can make the functionality work: Declare the FirebaseAuth reference, plus add another variable that we will need later on: FirebaseAuth auth; private static final int RC_SIGN_IN = 17; Now, inside your onCreate method, add the following code: auth = FirebaseAuth.getInstance(); if(auth.getCurrentUser() != null) { Log.d("Auth", "Logged in successfully"); } else { startActivityForResult( AuthUI.getInstance() .createSignInIntentBuilder() .setAvailableProviders( Arrays.asList(new AuthUI.IdpConfig.Builder( AuthUI.EMAIL_PROVIDER).build())).build(), RC_SIGN_IN);findViewById(R.id.logoutBtn) .setOnClickListener(this); Now, in your activity, implement the View.OnClick listener. So your class will look like the following: public class MainActivity extends AppCompatActivity implements View.OnClickListener {} After that, implement the onClick function as shown here: @Override public void onClick(View v) { if(v.getId() == R.id.logoutBtn) { AuthUI.getInstance().signOut(this) .addOnCompleteListener( new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { Log.d("Auth", "Logged out successfully"); // TODO: make custom operation. } }); } } In the end, implement the onActivityResult method as shown in the following code block: @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == RC_SIGN_IN) { if(resultCode == RESULT_OK) { //User is in ! Log.d("Auth",auth.getCurrentUser().getEmail()); } else { //User is not authenticated Log.d("Auth", "Not Authenticated"); } } } Now build and run your project. You will have a similar interface to that shown in the following screenshot: Figure 8: Android authentication using email/password:  email picker This interface will be shown in case you're not authenticated and your application will list all the saved accounts on your device. If you click on the NONE OF THE ABOVE button, you will be prompted with the following interface: Figure 9: Android authentication email/password: adding new email When you add your email and click on the NEXT button, the API will go and look for that user with that email in your application's users. If such an email is present, you will be authenticated, but if it's not the case, you will be redirected to the Sign-up activity as shown in the following screenshot: Figure 10: Android authentication: creating a new account, with email/password/name Next, you will add your name and password. And with that, you will create a new account and you will be authenticated. How it works... From the preceding code, it's clear that we didn't create any user interface. The Firebase UI is so powerful, so let's explore what happens: The setAvailableProviders method will take a list of providers—those providers will be different based on your needs, so it can be any email provider, Google, Facebook, and each and every provider that Firebase supports. The main difference is that each and every provider will have each separate configuration and necessary dependencies that you will need to support the functionality. Also, if you've noticed, we're setting up a logout button. We created this button mainly to log out our users and added a click listener to it. The idea here is that when you click on it, the application performs the Sign-out operation. Then you add your custom intent that will vary from a redirect to closing the application. If you noticed, we're implementing the onActivityResult special function and this one will be our main listening point whenever we connect or disconnect from the application. Within it, we can perform different operations from resurrection to displaying toasts, to anything that you can think of. Implementing Google Sign-in authentication Google authentication is the process of logging in/creating an account using nothing but your existing Google account. It's easy, fast, and intuitive and removes a lot of hustle we face, usually when we register any web/mobile application. I'm talking basically about form filling. Using Firebase Google Sign-in authentication, we can manage such functionality; plus we have had the user basic metadata such as the display name, picture URL, and more. In this recipe, we're going to see how we can implement Google Sign-in functionality for both Android and iOS. Before doing any coding, it's important to do some basic configuration in our Firebase Project console. Head directly to your Firebase project Console | Authentication | SIGN-IN METHOD | Google and simply activate the switch and follow the instructions there in order to get the client. Please notice that Google Sign-in is automatically configured for iOS, but for Android, we will need to do some custom configuration. Let us first look at getting ready for Android to implement Google Sign-in authentication: Before we start implementing the authentication functionality, we will need to install some dependencies first, so please head to your build.gradle file and paste the following, and then sync your build: compile 'com.google.firebase:firebase-auth:11.4.2' compile 'com.google.android.gms:play-services- auth:11.4.2' The dependency versions are dependable, and that means that whenever you want to install them, you will have to provide the same version for both dependencies. Moving on to getting ready  in iOS for implementation of Google Sign-in authentication: In iOS, we will need to install a couple of dependencies, so please go and edit your Podfile and add the following lines underneath your already present dependencies, if you have any: pod 'Firebase/Auth' pod 'GoogleSignIn' Now, in your terminal, type the following command: ~> pod install This command will install the required dependencies and configure your project accordingly. How to do it... First, let us take a look at how we will implement this recipe in Android: Now, after installing our dependencies, we will need to create the UI for our calls. To do that, simply copy and paste the following special button XML code into your layout: <com.google.android.gms.common.SignInButton android:id="@+id/gbtn" android:layout_width="368dp" android:layout_height="wrap_content" android:layout_marginLeft="16dp" android:layout_marginTop="30dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_marginRight="16dp" app:layout_constraintRight_toRightOf="parent" /> The result will be this: Figure 11: Google Sign-in button after the declaration After doing that, let's see the code behind it: SignInButton gBtn; FirebaseAuth mAuth; GoogleApiClient mGoogleApiClient; private final static int RC_SIGN_IN = 3; FirebaseAuth.AuthStateListener mAuthListener; @Override protected void onStart() { super.onStart(); mAuth.addAuthStateListener(mAuthListener); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mAuth = FirebaseAuth.getInstance(); gBtn = (SignInButton) findViewById(R.id.gbtn); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { signIn(); } }); mAuthListener = new FirebaseAuth.AuthStateListener() { @Override public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { if(firebaseAuth.getCurrentUser() != null) { AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create(); alertDialog.setTitle("User"); alertDialog.setMessage("I have a user loged in"); alertDialog.show(); } } }; mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { Toast.makeText(MainActivity.this, "Something went wrong", Toast.LENGTH_SHORT).show(); } }) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .build(); } GoogleSignInOptions gso = new GoogleSignInOptions.Builder( GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .build(); private void signIn() { Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent( mGoogleApiClient); startActivityForResult(signInIntent, RC_SIGN_IN); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_SIGN_IN) { GoogleSignInResult result = Auth.GoogleSignInApi .getSignInResultFromIntent(data); if (result.isSuccess()) { // Google Sign In was successful, authenticate with Firebase GoogleSignInAccount account = result.getSignInAccount(); firebaseAuthWithGoogle(account); } else { Toast.makeText(MainActivity.this, "Connection Error", Toast.LENGTH_SHORT).show(); } } } private void firebaseAuthWithGoogle( GoogleSignInAccount account) { AuthCredential credential = GoogleAuthProvider.getCredential( account.getIdToken(), null); mAuth.signInWithCredential(credential) .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { // Sign in success, update UI with the signed-in user's information Log.d("TAG", "signInWithCredential:success"); FirebaseUser user = mAuth.getCurrentUser(); Log.d("TAG", user.getDisplayName()); } else { Log.w("TAG", "signInWithCredential:failure", task.getException()); Toast.makeText(MainActivity.this, "Authentication failed.", Toast.LENGTH_SHORT) .show(); } // ... } }); } Then, simply build and launch your application, click on the authentication button, and you will be greeted with the following screen: Figure 12: Account picker, after clicking on Google Sign-in button. Next, simply pick the account you want to connect with, and then you will be greeted with an alert, finishing the authentication process. Now we will take a look at an implementation of our recipe in iOS: Before we do anything, let's import the Google Sign-in as follows: import GoogleSignIn After that, let's add our Google Sign-in button; to do so, go to your Login Page ViewController and add the following line of code: //Google sign in let googleBtn = GIDSignInButton() googleBtn.frame =CGRect(x: 16, y: 50, width: view.frame.width - 32, height: 50) view.addSubview(googleBtn) GIDSignIn.sharedInstance().uiDelegate = self The frame positioning is for my own needs—you can use it or modify the dimension to suit your application needs. Now, after adding the lines above, we will get an error. This is due to our ViewController not working well with the GIDSignInUIDelegate, so in order to make our xCode happier, let's add it to our ViewModal declaration so it looks like the following: class ViewController: UIViewController, FBSDKLoginButtonDelegate, GIDSignInUIDelegate {} Now, if you build and run your project, you will get the following: Figure 13: iOS application after configuring the Google Sign-in button Now, if you click on the Sign in button, you will get an exception. The reason for that is that the Sign in button is asking for the clientID, so to fix that, go to your AppDelegate file and complete the following import: import GoogleSignIn Next, add the following line of code within the application: didFinishLaunchingWithOptions as shown below: GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID If you build and run the application now, then click on the Sign in button, nothing will happen. Why? Because iOS doesn't know how and where to navigate to next. So now, in order to fix that issue, go to your GoogleService-Info.plist file, copy the value of the REVERSED_CLIENT_ID, then go to your project configuration. Inside the Info section, scroll down to the URL types, add a new URL type, and paste the link inside the URL Schemes field: Figure 14: Xcode Firebase URL schema adding, to finish the Google Sign-in behavior Next, within the application: open URL options, add the following line: GIDSignIn.sharedInstance().handle(url, sourceApplication:options[ UIApplicationOpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplicationOpenURLOptionsKey.annotation]) This will simply help the transition to the URL we already specified within the URL schemes. Next, if you build and run your application, tap on the Sign in button and you will be redirected using the SafariWebViewController to the Google Sign-in page, as shown in the following screenshot: Figure 15: iOS Google account picker after clicking on Sign-in button With that, the ongoing authentication process is done, but what will happen when you select your account and authorize the application? Typically, you need to go back to your application with all the needed profile information, don't you? isn't? Well, for now, it's not the case, so let's fix that. Go back to the AppDelegate file and do the following: Add the GIDSignInDelegate to the app delegate declaration Add the following line to the application: didFinishLaunchingWithOptions: GIDSignIn.sharedInstance().delegate = self This will simply let us go back to the application with all the tokens we need to finish the authentication process with Firebase. Next, we need to implement the signIn function that belongs to the GIDSignInDelegate; this function will be called once we're successfully authenticated: func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) { if let err = error { print("Can't connect to Google") return } print("we're using google sign in", user) } Now, once you're fully authenticated, you will receive the success message over your terminal. Now we can simply integrate our Firebase authentication logic. Complete the following import: import FirebaseAuth  Next, inside the same signIn function, add the following: guard let authentication = user.authentication else { return } let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken, accessToken: authentication.accessToken) Auth.auth().signIn(with: credential, completion: {(user, error) in if let error = error { print("[*] Can't connect to firebase, with error :", error) } print("we have a user", user?.displayName) }) This code will use the successfully logged in user token and call the Firebase Authentication logic to create a new Firebase user. Now we can retrieve the basic profile information that Firebase delivers. How it works... Let's explain what we did in the Android section: We activated authentication using our Google account from the Firebase project console. We also installed the required dependencies, from Firebase Auth to Google services. After finishing the setup, we gained the ability to create that awesome Google Sign-in special button, and we also gave it an ID for easy access. We created references from SignInButton and FirebaseAuth. Let's now explain what we just did in the iOS section: We used the GIDSignButton in order to create the branded Google Sign-in button, and we added it to our ViewController. Inside the AppDelegate, we made a couple of configurations so we could retrieve our ClientID that the button needed to connect to our application. For our button to work, we used the information stored in GoogleService-Info.plist and created an app link within our application so we could navigate to our connection page. Once everything was set, we were introduced to our application authorization page where we authorized the application and chose the account we wanted to use to connect. In order to get back all the required tokens and account information, we needed to go back to the AppDelegate file and implement the GIDSignInDelegate. Within it, we could can all the account-related tokens and information, once we were successful authenticated. Within the implemented SignIn function, we injected our regular Firebase authentication signIn method with all necessary tokens and information. When we built and ran the application again and signed in, we found the account used to authenticate, present in the Firebase authenticated account. To summarize, we learned how to integrate Firebase within a native context, basically over an iOS and Android application. If you've enjoyed reading this, do check,'Firebase Cookbook' for recipes to help you understand features of Firebase and implement them in your existing web or mobile applications. Using the Firebase Real-Time Database How to integrate Firebase with NativeScript for cross-platform app development Build powerful progressive web apps with Firebase  
Read more
  • 0
  • 0
  • 4199

article-image-firebase-nativescript-cross-platform-app-development
Savia Lobo
22 May 2018
16 min read
Save for later

How to integrate Firebase with NativeScript for cross-platform app development

Savia Lobo
22 May 2018
16 min read
NativeScript is now considered as one of the hottest platforms attracting developers. By using XML, JavaScript (also Angular), minor CSS for the visual aspects, and the magical touch of incorporating native SDKs, the platform has adopted the best of both worlds. Plus, this allows applications to be cross-platform, which means your application can run on both Android and iOS! In this tutorial, we're going to see how we can use Firebase to create some awesome native applications. This article is an excerpt taken from the book,' Firebase Cookbook', written by Houssem Yahiaoui. Getting started with NativeScript project In order to start a NativeScript project, we will need to make our development environment Node.js ready. So, in order to do so, let's download Node.js. Head directly to https://nodejs.org/en/download/ and download the most suitable version for your OS. After you have successfully installed Node.js, you will have two utilities. One is the Node.js executable and the other will be npm or the node package manager. This will help us download our dependencies and install NativeScript locally. How to do it... In your terminal/cmd of choice, type the following command: ~> npm install -g nativescript After installing NativeScript, you will need to add some dependencies. To know what your system is missing, simply type the following command: ~> tns doctor This command will test your system and make sure that everything is in place. If not, you'll get the missing parts. In order to create a new project, you will have many options to choose from. Those options could be creating a new project with vanilla JavaScript, with Typescript, from a template, or even better, using Angular. Head directly to your working directory and type the following command: ~> tns create <application-name> This command will initialize your project and install the basic needed dependencies. With that done, we're good to start working on our NativeScript project. Adding the Firebase plugin to our application One of NativeScript's most powerful features is the possibility of incorporating truly native SDKs. So, in this context, we can install the Firebase NativeScript on Android using the normal Gradle installation command. You can also do it on iOS via a Podfile if you are running macOS and want to create an iOS application along the way. However, the NativeScript ecosystem is pluggable, which means the ecosystem has plugins that extend certain functionalities. Those plugins usually incorporate native SDKs and expose the functionalities using JavaScript so we can exploit them directly within our application. In this recipe, we're going to use the wonderfully easy-to-use Eddy Verbruggen Firebase plugin, so let's see how we can add it to our project. How to do it... Head to your terminal/cmd of choice, type the following command, and hit Return/Enter respectively: tns plugin add nativescript-plugin-firebase This command will install the necessary plugin and do the required configuration. To find out the id, open your package.json file where you will find the NativeScript value: "nativescript": { "id": "org.nativescript.<your-app-name>" } Copy the id that you found in the preceding step and head over to your Firebase project console. Create a new Android/iOS application and paste that ID over your bundle name. Download the google-service.json/GoogleServices-Info.plist files and paste google-server.json in your app/Application_Resources/Android folder if you created an Android project. If you've created an iOS project, then paste the GoogleServices-Info.plist in the app/Application_Resources/iOS folder. Pushing/retrieving data from the Firebase Real-time Database Firebase stores data in a link-based manner that allows you to add and query the information really simple. The NativeScript Firebase plugin makes the operation much simpler with an easy-to-use API. So, let's discover how we can perform such operations. In this recipe, we're going to see how we can add and retrieve data in NativeScript and Firebase. Before we begin, we need to make sure that our application is fully configured with Firebase. You will also need to initialize the Firebase plugin with the application. To do that, open your project, head to your app.js file, and add the following import code: var firebase = require("nativescript-plugin- firebase"); This will import the Firebase NativeScript plugin. Next, add the following lines of code: firebase.init({}).then((instance) => { console.log("[*] Firebase was successfully initialised"); }, (error) => { console.log("[*] Huston we've an initialization error: " + error); }); The preceding code will simply go and initialize Firebase within our application. How to do it... After initializing our application, let's see how we can push some data to our Firebase Realtime Database. Let's start first by adding our interface, which will look similar to the one (Figure 1): Figure 1: Ideas adding page. The code behind it is as follows, and you can use this to implement the addition of new data to your bucket: <Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="onNavigatingTo" class="page"> <Page.actionBar> <ActionBar title="Firebase CookBook" class="action-bar"> </ActionBar> </Page.actionBar> <StackLayout class="p-20"> <TextField text="{{ newIdea }}" hint="Add here your shiny idea"/> <Button text="Add new idea to my bucket" tap="{{ addToMyBucket }}" </span>class</span>="btn btn-primary btn- active"/> </StackLayout> </Page> Now let's see the JavaScript related to this UI for our behavior. Head to your view-model and add the following snippets inside the createViewModel function: viewModel.addToMyBucket = () => { firebase.push('/ideas', { idea: viewModel.newIdea }).then((result) => { console.log("[*] Info : Your data was pushed !"); }, (error) => { console.log("[*] Error : While pushing your data to Firebase, with error: " + error); }); } If you check your Firebase database, you will find your new entry present there. Once your data is live, you will need to think of a way to showcase all your shiny, new ideas. Firebase gave us a lovely event that we shall listen to whenever a new child element is created. The following code teaches you how to create the event for showcasing the addition of new child elements: var onChildEvent = function(result) { console.log("Idea: " + JSON.stringify(result.value)); }; firebase.addChildEventListener(onChildEvent, "/ideas").then((snapshot) => { console.log("[*] Info : We've some data !"); }); After getting the newly-added child, it's up to you to find the proper way to bind your ideas. They are mainly going to be either lists or cards, but they could be any of the previously mentioned ones. To run and experience your new feature, use the following command: ~> tns run android # for android ~> tns run ios # for ios How it works... So what just happened? We defined a basic user interface that will serve us by adding those new ideas to our Firebase console application. Next, the aim was to save all that information inside our Firebase Realtime Database using the same schema that Firebase uses. This is done via specifying a URL where all your information will be stored and then specifying the data schema. This will finally hold and define the way our data will be stored. We then hooked a listener to our data URL using firebase.addChildEventListener. This will take a function where the next item will be held and the data URL that we want our listener hook to listen on. In case you're wondering how this module or service works in NativeScript, the answer is simple. It's due to the way NativeScript works; because one of NativeScript's powerful features is the ability to use native SDKs. So in this case, we're using and implementing the Firebase Database Android/iOS SDKs for our needs, and the plugin APIs we're using are the JavaScript abstraction of how we want to exploit our native calls. Authenticating using anonymous or password authentication As we all know, Firebase supports both anonymous and password-based authentication, each with its own, suitable use case. So in this recipe, we're going to see how we can perform both anonymous and password authentication. You will need to initialize the Firebase plugin with the application. To do that, open your project, head to your app.js file, and add the following import: var firebase = require("nativescript-plugin- firebase"); This will import the Firebase NativeScript plugin. Next, add the following lines of code: firebase.init({}).then((instance) => { console.log("[*] Firebase was successfully initialised"); }, (error) => { console.log("[*] Huston we've an initialization error: " + error); }); The preceding code will go and initialize Firebase within our application. How to do it... Before we start, we need to create some UI elements. Your page will look similar to this one after you finish (Figure 2): Figure 2: Application login page. Now open your login page and add the following code snippets there: <Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="onNavigatingTo" class="page"> <Page.actionBar> <ActionBar title="Firebase CookBook" icon="" class="action-bar"> </ActionBar> </Page.actionBar> <StackLayout> <Label text="Login Page" textWrap="true" style="font-weight: bold; font-size: 18px; text-align: center; padding:20"/> <TextField hint="Email" text="{{ user_email }}" /> <TextField hint="Password" text="{{ user_password }}" secure="true"/&gt;<Button text="LOGIN" tap="{{ passLogin }}" class="btn btn-primary btn-active" /> <Button text="Anonymous login" tap="{{ anonLogin }}" class="btn btn-success"/> </StackLayout> </Page> Save that. Let's now look at the variables and functions in our view-model file. For that, let's implement the passLogin and anonLogin functions. The first one will be our normal email and password authentication, and the second will be our anonymous login function. To make this implementation come alive, type the following code lines on your page: viewModel.anonLogin = () => { firebase.login({ type: firebase.LoginType.ANONYMOUS }).then((result) => { console.log("[*] Anonymous Auth Response:" + JSON.stringify(result)); },(errorMessage) => { console.log("[*] Anonymous Auth Error: "+errorMessage); }); } viewModel.passLogin = () => { let email = viewModel.user_email; let pass = viewModel.user_password; firebase.login({ type: firebase.LoginType.PASSWORD, passwordOptions: { email: email, password: pass } }).then((result) => { console.log("[*] Email/Pass Response : " + JSON.stringify(result)); }, (error) => { console.log("[*] Email/Pass Error : " + error); }); } Now, simply save your file and run it using the following command: ~> tns run android # for android ~> tns run ios # for ios How it works... Let's quickly understand what we've just done in the recipe: We've built the UI we needed as per the authentication type. If we want the email and password one, we will need the respective fields, whereas, for anonymous authentication, all we need is a button. Then, for both functions, we call the Firebase login button specifying the connection type for both cases. After finishing that part, it's up to you to define what is next and to retrieve that metadata from the API for your own needs later on. Authenticating using Google Sign-In Google Sign-In is one of the most popular integrated services in Firebase. It does not require any extra hustle, has the most functionality, and is popular among many apps. In this recipe, we're going to see how we can integrate Firebase Google Sign-In with our NativeScript project. You will need to initialize the Firebase plugin within the application. To do that, open your project, head to your app.js file, and add the following line: var firebase = require("nativescript-plugin- firebase"); This will import the Firebase NativeScript plugin. Next, add the following lines of code: firebase.init({}).then((instance) => { console.log("[*] Firebase was successfully initialised"); }, (error) => { console.log("[*] Huston we've an initialization error: " + error); }); The preceding code will go and initialize Firebase within our application. We will also need to install some dependencies. For that, underneath the NativeScript-plugin-firebase folder | platform | Android | include.gradle file, uncomment the following entry for Android: compile "com.google.android.gms:play-services- auth:$googlePlayServicesVersion" Now save and build your application using the following command: ~> tns build android Or uncomment this entry if you're building an iOS application: pod 'GoogleSignIn' Then, build your project using the following command: ~> tns build ios How to do it... First, you will need to create your button. So for this to happen, please go to your login-page.xml file and add the following button declaration: <Button text="Google Sign-in" tap="{{ googleLogin }}" class="btn" style="color:red"/> Now let's implement the googleLogin() function by using the following code snippet: viewModel.googleLogin = () => { firebase.login({ type: firebase.LoginType.GOOGLE, }).then((result) => { console.log("[*] Google Auth Response: " + JSON.</span>stringify(result)); },(errorMessage) => { console.log("[*] Google Auth Error: " + errorMessage); }); } To build and experience your new feature, use the following command: ~> tns run android # for android ~> tns run ios # for ios Now, once you click on the Google authentication button, you should have the following (Figure 3): Figure 3: Account picking after clicking on Google Login button. Don't forget to add your SHA-1 fingerprint code or the authentication process won't finish. How it works... Let's explain what just happened in the preceding code: We added the new button for the Google authentication. Within the tap event of this button, we gave it the googleLogin() function. Within  googleLogin(), we used the Firebase login button giving it firebase.LoginType.GOOGLE as type. Notice that, similar to normal Google authentication on a web platform, we can also give the hd or the hostedDomain option. We could also use the option of filtering the connection hosting we want by adding the following option under the login type: googleOptions: { hostedDomain: "<your-host-name>" } The hd option or the hostedDomain is simply what's after the @ sign in an email address. So, for example, in the email ID cookbook@packtpub.com the hosted domain is packtpub.com. For some apps, you might want to limit the email ID used by users when they connect to your application to just that host. This can be done by providing only the hostedDomain parameter in the code line pertaining to the storage of the email address. When you look at the actual way we're making these calls, you will see that it's due to the powerful NativeScript feature that lets us exploit native SDK. If you remember the Getting ready section of this recipe, we uncommented a section where we installed the native SDK for both Android and iOS. Besides the NativeScript firebase plugin, you can also exploit the Firebase Auth SDK, which will let you exploit all supported Firebase authentication methods. Adding dynamic behavior using Firebase Remote Config Remote Config is one of the hottest features of Firebase and lets us play with all the different application configurations without too much of a headache. By a headache, we mean the process of building, testing, and publishing, which usually takes a lot of our time, even if it's just to fix a small float number that might be wrong. So in this recipe, we're going to see how we can use Firebase Remote Config within our application. In case you didn't choose the functionality by default when you created your application, please head to your build.gradle and Podfile and uncomment the Firebase Remote Config line in both files or in the environment you're using with your application. How to do it... Actually, the integration part of your application is quite easy. The tricky part is when you want to toggle states or alter some configuration. So think upon that heavily, because it will affect how your application works and will also affect the way you change properties. Let's suppose that within this NativeScript application we want to have a mode called Ramadan mode. We want to create this mode for a special month where we wish to offer discounts, help our users with new promos, or even change our user interface to suit the spirit of it. So, let's see how we can do that: firebase.getRemoteConfig({ developerMode: true, cacheExpirationSeconds: 1, properties: [{ key: "ramadan_promo_enabled", default: false } }).then(function (result) { console.log("Remote Config: " + JSON.stringify( result.properties.ramadan_promo_enabled)); //TODO : Use the value to make changes. }); In the preceding code, and because we are still in development mode, we set that we want the developerMode to be activated. We also set the cacheExpirationSeconds to be one second. This is important because we don't want our settings to take a long time until they affect our application during the development phase. This will set the throttled mode to true, which will make the application fetch or look for new data every second to our Firebase remote configurations. We can set the default values of each and every item within our Firebase remote configuration. This value will be the starting point for fetching any new values that might be present over the Firebase project console. Now, let's see how we can wire that value from the project console. To do this, head to your Firebase project Console | Remote Config Section | ADD YOUR FIRST PARAMETER Button (Figure 4): Figure 4: Firebase Remote Config Parameter adding section. Next, you will get a modal where you will add your properties and their values. Make sure to add the exact same one that's in your code otherwise it won't work. The following screenshot shows the PARAMETERS tab of the console where you will add the properties (Figure 5): Figure 5: While adding the new parameter After adding them, click on the PUBLISH CHANGES button (Figure 6): Figure 6: Publishing the new created Parameter. With that, you're done. Exit your application and open it back up again. Watch how your console and your application fetches the new values. Then, it's up to you and your application to make the needed changes once the values are changed. How it works... Let's explain what just happened: We added back our dependencies from the build.gradle and Podfile so we can support the functionality we want to use. We've selected and added the code that will be responsible for giving the default values and for fetching the new changes. We have also activated the developer mode, which will help out in our development and staging phases. This mode will be disabled once we're in production. We've set the cache expiration time, which is essential while being in development so we can retrieve those values in a fast way. This too will be changed in production, by giving the cache more expiration time, because we don't want to jeopardize our application with high-throttled operations every second. We've added our support config in our Firebase Remote Config parameters, gave it the necessary value, and published it. This final step will control the way our application feels and looks like each new change. We learned how to integrate Firebase with NativeScript using various recipes. If you've enjoyed this article, do check out 'Firebase Cookbook' to change the way you develop and make your app a first class citizen of the cloud.
Read more
  • 0
  • 0
  • 12428

article-image-chat-application-kotlin-node-js-javascript
Sugandha Lahoti
14 May 2018
30 min read
Save for later

Building chat application with Kotlin using Node.js, the powerful Server-side JavaScript platform

Sugandha Lahoti
14 May 2018
30 min read
When one mentions server-side JavaScript technology, Node.js is what comes to our mind first. Node.js is an extremely powerful and robust platform. Using this JavaScript platform, we can build server-side applications very easily. In today's tutorial, we will focus on creating a chat application that uses Kotlin by using the Node.js technology. So, basically, we will transpile Kotlin code to JavaScript on the server side. This article is an excerpt from the book, Kotlin Blueprints, written by Ashish Belagali, Hardik Trivedi, and Akshay Chordiya. With this book, you will get to know the building blocks of Kotlin and best practices when using quality world-class applications. Kotlin is a modern language and is gaining popularity in the JavaScript community day by day. The Kotlin language with modern features and statically typed; is superior to JavaScript. Similar to JavaScript, developers that know Kotlin can use the same language skills on both sides but, they also have the advantage of using a better language. The Kotlin code gets transpiled to JavaScript and that in turn works with the Node.js. This is the mechanism that lets you use the Kotlin code to work with a server-side technology, such as Node.js. Creating a chat application Our chat app will have following functionalities: User can log in by entering their nickname User can see the list of online users User will get notified when a new user joins User can receive chats from anyone User can perform a group chat in a chat room User will receive a notification when any user leaves the chat To visualize the app that we will develop, take a look at the following screenshots. The following screenshot is a page where the user will enter a nickname and gain an entry in our chat app: In the following screen, you can see a chat window and a list of online users: We have slightly configured this application in a different way. We have kept the backend code module and frontend code module separate using the following method: Create a new project named kotlin_node_chat_app Now, create a new Gradle module named backend and select Kotlin (JavaScript) under the libraries and additional information window, and follow the remaining steps. Similarly, also create a Gradle module named webapp. The backend module will contain all the Kotlin code that will be converted into Node.JS code later, and the webapp module will contain all the Kotlin code that will later be converted into the JavaScript code. We have referred to the directory structure from Github. After performing the previous steps correctly, your project will have three build.gradle files. We have highlighted all three files in the project explorer section, as shown in the following screenshot: Setting up the Node.js server We need to initialize our root directory for the node. Execute npm init and it will create package.json. Now our login page is created. To run it, we need to set up the Node.js server. We want to create the server in such a way that by executing npm start, it should start the server. To achieve it, our package.json file should look like the following piece of code: { "name": "kotlin_node_chat_app", "version": "1.0.0", "description": "", "main": "backend/server/app.js", "scripts": { "start": "node backend/server/app.js" }, "author": "Hardik Trivedi", "license": "ISC", "dependencies": { "ejs": "^2.5.7", "express": "^4.16.2", "kotlin": "^1.1.60", "socket.io": "^2.0.4" } } We have specified a few dependencies here as well: EJS to render HTML pages Express.JS as its framework, which makes it easier to deal with Node.js Kotlin, because, ultimately, we want to write our code into Kotlin and want it compiled into the Node.js code Socket.IO to perform chat Execute npm install on the Terminal/Command Prompt and it should trigger the download of all these dependencies. Specifying the output files Now, it's very important where your output will be generated once you trigger the build. For that, build.gradle will help us. Specify the following lines in your module-level build.gradle file. The backend module's build.gradle will have the following lines of code: compileKotlin2Js { kotlinOptions.outputFile = "${projectDir}/server/app.js" kotlinOptions.moduleKind = "commonjs" kotlinOptions.sourceMap = true } The webapp module's build.gradle will have the following lines of code: compileKotlin2Js { kotlinOptions.metaInfo = true kotlinOptions.outputFile = "${projectDir}/js/main.js" kotlinOptions.sourceMap = true kotlinOptions.main = "call" } In both the compileKotlin2Js nodes, kotlinOptions.outputFile plays a key role. This basically tells us that once Kotlin's code gets compiled, it will generate app.js and main.js for Node.js and JavaScript respectively. In the index.ejs file, you should define a script tag to load main.js. It will look something like the following line of code: <script type="text/javascript" src="js/main.js"></script> Along with this, also specify the following two tags: <script type="text/javascript" src="lib/kotlin/kotlin.js"></script> <script type="text/javascript" src="lib/kotlin/kotlinx-html-js.js"> </script> Examining the compilation output The kotlin.js and kotlinx-html-js.js files are nothing but the Kotlin output files. It's not compilation output, but actually transpiled output. The following are output compilations: kotlin.js: This is the runtime and standard library. It doesn't change between applications, and it's tied to the version of Kotlin being used. {module}.js: This is the actual code from the application. All files are compiled into a single JavaScript file that has the same name as the module. {file}.meta.js: This metafile will be used for reflection and other functionalities. Let's assume our final Main.kt file will look like this: fun main(args: Array<String>) { val socket: dynamic = js("window.socket") val chatWindow = ChatWindow { println("here") socket.emit("new_message", it) } val loginWindow = LoginWindow { chatWindow.showChatWindow(it) socket.emit("add_user", it) } loginWindow.showLogin() socket.on("login", { data -> chatWindow.showNewUserJoined(data) chatWindow.showOnlineUsers(data) }) socket.on("user_joined", { data -> chatWindow.showNewUserJoined(data) chatWindow.addNewUsers(data) }) socket.on("user_left", { data -> chatWindow.showUserLeft(data) }) socket.on("new_message", { data -> chatWindow.showNewMessage(data) }) } For this, inside main.js, our main function will look like this: function main(args) { var socket = window.socket; var chatWindow = new ChatWindow(main$lambda(socket)); var loginWindow = new LoginWindow(main$lambda_0(chatWindow, socket)); loginWindow.showLogin(); socket.on('login', main$lambda_1(chatWindow)); socket.on('user_joined', main$lambda_2(chatWindow)); socket.on('user_left', main$lambda_3(chatWindow)); socket.on('new_message', main$lambda_4(chatWindow)); } The actual main.js file will be bulkier because it will have all the code transpiled, including other functions and LoginWindow and ChatWindow classes. Keep a watchful eye on how the Lambda functions are converted into simple JavaScript functions. Lambda functions, for all socket events, are transpiled into the following piece of code: function main$lambda_1(closure$chatWindow) { return function (data) { closure$chatWindow.showNewUserJoined_qk3xy8$(data); closure$chatWindow.showOnlineUsers_qk3xy8$(data); }; } function main$lambda_2(closure$chatWindow) { return function (data) { closure$chatWindow.showNewUserJoined_qk3xy8$(data); closure$chatWindow.addNewUsers_qk3xy8$(data); }; } function main$lambda_3(closure$chatWindow) { return function (data) { closure$chatWindow.showUserLeft_qk3xy8$(data); }; } function main$lambda_4(closure$chatWindow) { return function (data) { closure$chatWindow.showNewMessage_qk3xy8$(data); }; } As can be seen, Kotlin aims to create very concise and readable JavaScript, allowing us to interact with it as needed. Specifying the router We need to write a behavior in the route.kt file. This will let the server know which page to load when any request hits the server. The router.kt file will look like this: fun router() { val express = require("express") val router = express.Router() router.get("/", { req, res -> res.render("index") }) return router } This simply means that whenever a get request with no name approaches the server, it should display an index page to the user. We are told to instruct the framework to refer to the router.kt file by writing the following line of code: app.use("/", router()) Starting the node server Now let's create a server. We should create an app.kt file under the backend module at the backend/src/kotlin path. Refer to the source code to verify. Write the following piece of code in app.kt: external fun require(module: String): dynamic external val process: dynamic external val __dirname: dynamic fun main(args: Array<String>) { println("Server Starting!") val express = require("express") val app = express() val path = require("path") val http = require("http") /** * Get port from environment and store in Express. */ val port = normalizePort(process.env.PORT) app.set("port", port) // view engine setup app.set("views", path.join(__dirname, "../../webapp")) app.set("view engine", "ejs") app.use(express.static("webapp")) val server = http.createServer(app) app.use("/", router()) app.listen(port, { println("Chat app listening on port http://localhost:$port") }) } fun normalizePort(port: Int) = if (port >= 0) port else 7000 These are multiple things to highlight here: external: This is basically an indicator for Kotlin that the line written along with this a pure JavaScript code. Also, when this code gets compiled into the respected language, the compiler understands that the class, function, or property written along with that will be provided by the developer, and so no JavaScript code should be generated for that invocation. The external modifier is automatically applied to nested declarations. For example, consider the following code block. We declare the class as external and automatically all its functions and properties are treated as external: external class Node { val firstChild: Node fun append(child: Node): Node fun removeChild(child: Node): Node // etc } dynamic: You will often see the usage of dynamic while working with JavaScript. Kotlin is a statically typed language, but it still has to interoperate with languages such as JavaScript. To support such use cases with a loosely or untyped programming language, dynamic is useful. It turns off Kotlin's type checker. A value of this type can be assigned to any variable or passed anywhere as a parameter. Any value can be assigned to a variable of dynamic type or passed to a function that takes dynamic as a parameter. Null checks are disabled for such values. require("express"): We typically use ExpressJS with Node.js. It's a framework that goes hand in hand with Node.js. It's designed with the sole purpose of developing web applications. A Node.js developer must be very familiar with it. process.env.PORT: This will find an available port on the server, as simple as that. This line is required if you want to deploy your application on a utility like Heroku. Also, notice the normalizePort function. See how concise it is. The if…else condition is written as an expression. No explicit return keyword is required. Kotlin compiler also identifies that if (port >= 0) port else 7000 will always return Int, hence no explicit return type is required. Smart, isn't it! __dirname: This is always a location where your currently executing script is present. We will use it to create a path to indicate where we have kept our web pages. app.listen(): This is a crucial one. It starts the socket and listens for the incoming request. It takes multiple parameters. Mainly, we will use two parameterized functions, that take the port number and connection callback as an argument. The app.listen() method is identical to http.Server.listen(). In Kotlin, it takes a Lambda function. Now, it's time to kick-start the server. Hit the Gradle by using ./gradlew build. All Kotlin code will get compiled into Node.js code. On Terminal, go to the root directory and execute npm start. You should be able to see the following message on your Terminal/Command Prompt: Creating a login page Now, let's begin with the login page. Along with that, we will have to enable some other settings in the project as well. If you refer to a screenshot that we mentioned at the beginning of the previous section, you can make out that we will have the title, the input filed, and a button as a part of the login page. We will create the page using Kotlin and the entire HTML tree structure, and by applying CSS to them, the will be part of our Kotlin code. For that, you should refer to the Main.kt and LoginWindow files. Creating an index.ejs file We will use EJS (effective JavaScript templating) to render HTML content on the page. EJS and Node.js go hand in hand. It's simple, flexible, easy to debug, and increases development speed. Initially, index.ejs would look like the following code snippet: <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial- scale=1.0"/> </head> <body> <div id="container" class="mainContainer"> </div> </body> </html> The <div> tag will contain all different views, for example, the Login View, Chat Window View, and so on. Using DSL DSL stands for domain-specific language. As the name indicates, it gives you the feeling as if you are writing code in a language using terminology particular to a given domain without being geeky, but then, this terminology is cleverly embedded as a syntax in a powerful language. If you are from the Groovy community, you must be aware of builders. Groovy builders allow you to define data in a semi-declarative way. It's a kind of mini-language of its own. Builders are considered good for generating XML and laying out UI components. The Kotlin DSL uses Lambdas a lot. The DSL in Kotlin is a type-safe builder. It means we can detect compilation errors in IntelliJ's beautiful IDE. The type-check builders are much better than the dynamically typed builders of Groovy. Using kotlinx.html The DSL to build HTML trees is a pluggable dependency. We, therefore, need to set it up and configure it for our project. We are using Gradle as a build tool and Gradle has the best way to manage the dependencies. We will define the following line of code in our build.gradle file to use kotlinx.html: compile("org.jetbrains.kotlinx:kotlinx-html-js:$html_version") Gradle will automatically download this dependency from jcenter(). Build your project from menu Build | Build Project. You can also trigger a build from the terminal/command prompt. To build a project from the Terminal, go to the root directory of your project and then execute ./gradlew build. Now create the index.ejs file under the webapp directory. At this moment, your index.ejs file may look like the following: Inside your LoginWindow class file, you should write the following piece of code: class LoginWindow(val callback: (String) -> Unit) { fun showLogin() { val formContainer = document.getElementById("container") as HTMLDivElement val loginDiv = document.create.div { id = "loginDiv" h3(classes = "title") { +"Welcome to Kotlin Blueprints chat app" } input(classes = "nickNameInput") { id = "nickName" onInputFunction = onInput() maxLength = 16.toString() placeholder = "Enter your nick name" } button(classes = "loginButton") { +"Login" onClickFunction = onLoginButtonClicked() } } formContainer.appendChild(loginDiv) } } Observe how we have provided the ID, input types, and a default ZIP code value. A default ZIP code value is optional. Let's spend some time understanding the previous code. The div, input, button, and h3 all these are nothing but functions. They are basically Lambda functions. The following are the functions that use Lambda as the last parameter. You can call them in different ways: someFunction({}) someFunction("KotlinBluePrints",1,{}) someFunction("KotlinBluePrints",1){} someFunction{} Lambda functions Lambda functions are nothing but functions without a name. We used to call them anonymous functions. A function is basically passed into a parameter of a function call, but as an expression. They are very useful. They save us a lot of time by not writing specific functions in an abstract class or interface. Lambda usage can be as simple the following code snippet, where it seems like we are simply binding a block an invocation of the helloKotlin function: fun main(args: Array<String>) { val helloKotlin={println("Hello from KotlinBlueprints team!")} helloKotlin() } At the same time, lambda can be a bit complex as well, just like the following code block: fun <T> lock(lock: Lock, body: () -> T): T { lock.lock() try { return body() } finally { lock.unlock() } } In the previous function, we are acquiring a lock before executing a function and releasing it when the function gets executed. This way, you can synchronously call a function in a multithreaded environment. So, if we have a use case where we want to execute sharedObject.someCrucialFunction() in a thread-safe environment, we will call the preceding lock function like this: lock(lock,{sharedObject.someCrucialFunction()}) Now, the lambda function is the last parameter of a function call, so it can be easily written like this: lock(lock) { sharedObject.someCrucialFunction() } Look how expressive and easy to understand the code is. We will dig more into the Lambda in the upcoming section. Reading the nickname In the index.ejs page, we will have an input field with the ID nickName when it is rendered. We can simply read the value by writing the following lines of code: val nickName = (document.getElementById("nickName") as? HTMLInputElement)?.value However, to cover more possibilities, we have written it in a slightly different way. We have written it as if we are taking the input as an event. The following code block will continuously read the value that is entered into the nickName input field: private fun onInput(): (Event) -> Unit { return { val input = it.currentTarget as HTMLInputElement when (input.id) { "nickName" -> nickName = input.value "emailId" -> email = input.value } } } Check out, we have used the when function, which is a replacement for the switch case. The preceding code will check whether the ID of the element is nickName or emailId, and, based on that, it will assign the value to the respective objects by reading them from the in-out field. In the app, we will only have the nickname as the input file, but using the preceding approach, you can read the value from multiple input fields. In its simplest form, it looks like this: when (x) { 1 -> print("x == 1") 2 -> print("x == 2") else -> { // Note the block print("x is neither 1 nor 2") } } The when function compares its argument against all branches, top to bottom until some branch condition is met. The when function can be used either as an expression or as a statement. The else branch is evaluated if none of the other branch conditions are satisfied. If when is used as an expression, the else branch is mandatory, unless the compiler can prove that all possible cases are covered with branch conditions. If many cases should be handled in the same way, the branch conditions may be combined with a comma, as shown in the following code: when (x) { 0, 1 -> print("x == 0 or x == 1") else -> print("otherwise") } The following uses arbitrary expressions (not only constants) as branch conditions: when (x) { parseInt(s) -> print("s encodes x") else -> print("s does not encode x") } The following is used to check a value for being in or !in a range or a collection: when (x) { in 1..10 -> print("x is in the range") in validNumbers -> print("x is valid") !in 10..20 -> print("x is outside the range") else -> print("none of the above") } Passing nickname to the server Once our setup is done, we are able to start the server and see the login page. It's time to pass the nickname or server and enter the chat room. We have written a function named onLoginButtonClicked(). The body for this function should like this: private fun onLoginButtonClicked(): (Event) -> Unit { return { if (!nickName.isBlank()) { val formContainer = document.getElementById("loginDiv") as HTMLDivElement formContainer.remove() callback(nickName) } } } The preceding function does two special things: Smart casting Registering a simple callback Smart cast Unlike any other programming language, Kotlin also provides class cast support. The document.getElementById() method returns an Element type if instance. We basically want it to cast into HTMLDivElement to perform some <div> related operation. So, using as, we cast the Element into HTMLDivElement. With the as keyword, it's unsafe casting. It's always better to use as?. On a successful cast, it will give an instance of that class; otherwise, it returns null. So, while using as?, you have to use Kotlin's null safety feature. This gives your app a great safety net onLoginButtonClicked can be refactored by modifying the code a bit. The following code block is the modified version of the function. We have highlighted the modification in bold: private fun onLoginButtonClicked(): (Event) -> Unit { return { if (!nickName.isBlank()) { val formContainer = document.getElementById("loginDiv") as? HTMLDivElement formContainer?.remove() callback(nickName) } } } Registering a callback Oftentimes, we need a function to notify us when something gets done. We prefer callbacks in JavaScript. To write a click event for a button, a typical JavaScript code could look like the following: $("#btn_submit").click(function() { alert("Submit Button Clicked"); }); With Kotlin, it's simple. Kotlin uses the Lambda function to achieve this. For the LoginWindow class, we have passed a callback as a constructor parameter. In the LoginWindow class (val callback: (String) -> Unit), the class header specifies that the constructor will take a callback as a parameter, which will return a string when invoked. To pass a callback, we will write the following line of code: callback(nickName) To consume a callback, we will write code that will look like this: val loginWindow = LoginWindow { chatWindow.showChatWindow(it) socket.emit("add_user", it) } So, when callback(nickName) is called, chatWindow.showChatWindow will get called and the nickname will be passed. Without it, you are accessing nothing but the nickname. Establishing a socket connection We shall be using the Socket.IO library to set up sockets between the server and the clients. Socket.IO takes care of the following complexities: Setting up connections Sending and receiving messages to multiple clients Notifying clients when the connection is disconnected Read more about Socket.IO at https://socket.io/. Setting up Socket.IO We have already specified the dependency for Socket.IO in our package.json file. Look at this file. It has a dependency block, which is mentioned in the following code block: "dependencies": { "ejs": "^2.5.7", "express": "^4.16.2", "kotlin": "^1.1.60", "socket.io": "^2.0.4" } When we perform npm install, it basically downloads the socket-io.js file and keeps node_modules | socket.io inside. We will add this JavaScript file to our index.ejs file. There we can find the following mentioned <script> tag inside the <body> tag: <script type="text/javascript" src="/socket.io/socket.io.js"> </script> Also, initialize socket in the same index.js file like this: <script> window.socket = io(); </script> Listening to events With the Socket.IO library, you should open a port and listen to the request using the following lines of code. Initially, we were directly using app.listen(), but now, we will pass that function as a listener for sockets: val io = require("socket.io").listen(app.listen(port, { println("Chat app listening on port http://localhost:$port") })) The server will listen to the following events and based on those events, it will perform certain tasks: Listen to the successful socket connection with the client Listen for the new user login events Whenever a new user joins the chat, add it to the online users chat list and broadcast it to every client so that they will know that a new member has joined the chat Listen to the request when someone sends a message Receive the message and broadcast it to all the clients so that the client can receive it and show it in the chat window Emitting the event The Socket.IO library works on a simple principle—emit and listen. Clients emit the messages and a listener listens to those messages and performs an action associated with them. So now, whenever a user successfully logs in, we will emit an event named add_user and the server will add it to an online user's list. The following code line emits the message: socket.emit("add_user", it) The following code snippet listens to the message and adds a user to the list: socket.on("add_user", { nickName -> socket.nickname= nickName numOfUsers = numOfUsers.inc() usersList.add(nickName as String) }) The socket.on function will listen to the add_user event and store the nickname in the socket. Incrementing and decrementing operator overloading There are a lot of things operator overloading can do, and we have used quite a few features here. Check out how we increment a count of online users: numOfUsers = numOfUsers.inc() It is a much more readable code compared to numOfUsers = numOfUsers+1, umOfUsers += 1, or numOfUsers++. Similarly, we can decrement any number by using the dec() function. Operator overloading applies to the whole set of unary operators, increment-decrement operators, binary operators, and index access operator. Read more about all of them here. Showing a list of online users Now we need to show the list of online users. For this, we need to pass the list of all online users and the count of users along with it. Using the data class The data class is one of the most popular features among Kotlin developers. It is similar to the concept of the Model class. The compiler automatically derives the following members from all properties declared in the primary constructor: The equals()/hashCode() pair The toString() of the User(name=John, age=42) form The componentN() functions corresponding to the properties in their order of declaration The copy() function A simple version of the data class can look like the following line of code, where name and age will become properties of a class: data class User(val name: String, val age: Int) With this single line and, mainly, with the data keyword, you get equals()/hasCode(), toString() and the benefits of getters and setters by using val/var in the form of properties. What a powerful keyword! Using the Pair class In our app, we have chosen the Pair class to demonstrate its usage. The Pair is also a data class. Consider the following line of code: data class Pair<out A, out B> : Serializable It represents a generic pair of two values. You can look at it as a key–value utility in the form of a class. We need to create a JSON object of a number of online users with the list of their nicknames. You can create a JSON object with the help of a Pair class. Take a look at the following lines of code: val userJoinedData = json(Pair("numOfUsers", numOfUsers), Pair("nickname", nickname), Pair("usersList", usersList)) The preceding JSON object will look like the following piece of code in the JSON format: { "numOfUsers": 3, "nickname": "Hardik Trivedi", "usersList": [ "Hardik Trivedi", "Akshay Chordiya", "Ashish Belagali" ] } Iterating list The user's list that we have passed inside the JSON object will be iterated and rendered on the page. Kotlin has a variety of ways to iterate over the list. Actually, anything that implements iterable can be represented as a sequence of elements that can be iterated. It has a lot of utility functions, some of which are mentioned in the following list: hasNext(): This returns true if the iteration has more elements hasPrevious(): This returns true if there are elements in the iteration before the current element next(): This returns the next element in the iteration nextIndex(): This returns the index of the element that would be returned by a subsequent call to next previous(): This returns the previous element in the iteration and moves the cursor position backward previousIndex(): This returns the index of the element that would be returned by a subsequent call to previous() There are some really useful extension functions, such as the following: .asSequence(): This creates a sequence that returns all elements from this iterator. The sequence is constrained to be iterated only once. .forEach(operation: (T) -> Unit): This performs the given operation on each element of this iterator. .iterator(): This returns the given iterator itself and allows you to use an instance of the iterator in a for the loop. .withIndex(): Iterator<IndexedValue<T>>: This returns an iterator and wraps each value produced by this iterator with the IndexedValue, containing a value, and its index. We have used forEachIndexed; this gives the extracted value at the index and the index itself. Check out the way we have iterated the user list: fun showOnlineUsers(data: Json) { val onlineUsersList = document.getElementById("onlineUsersList") onlineUsersList?.let { val usersList = data["usersList"] as? Array<String> usersList?.forEachIndexed { index, nickName -> it.appendChild(getUserListItem(nickName)) } } } Sending and receiving messages Now, here comes the interesting part: sending and receiving a chat message. The flow is very simple: The client will emit the new_message event, which will be consumed by the server, and the server will emit it in the form of a broadcast for other clients. When the user clicks on Send Message, the onSendMessageClicked method will be called. It sends the value back to the view using callback and logs the message in the chat window. After successfully sending a message, it clears the input field as well. Take a look at the following piece of code: private fun onSendMessageClicked(): (Event) -> Unit { return { if (chatMessage?.isNotBlank() as Boolean) { val formContainer = document.getElementById("chatInputBox") as HTMLInputElement callback(chatMessage!!) logMessageFromMe(nickName = nickName, message = chatMessage!!) formContainer.value = "" } } } Null safety We have defined chatMessage as nullable. Check out the declaration here: private var chatMessage: String? = null Kotlin is, by default, null safe. This means that, in Kotlin, objects cannot be null. So, if you want any object that can be null, you need to explicitly state that it can be nullable. With the safe call operator ?., we can write if(obj !=null) in the easiest way ever. The if (chatMessage?.isNotBlank() == true) can only be true if it's not null, and does not contain any whitespace. We do know how to use the Elvis operator while dealing with null. With the help of the Elvis operator, we can provide an alternative value if the object is null. We have used this feature in our code in a number of places. The following are some of the code snippets that highlight the usage of the safe call operator. Removing the view if not null: formContainer?.remove() Iterating over list if not null: usersList?.forEachIndexed { _, nickName -> it.appendChild(getUserListItem(nickName)) } Appending a child if the div tag is not null: onlineUsersList?.appendChild(getUserListItem (data["nickName"].toString())) Getting a list of all child nodes if the <ul> tag is not null: onlineUsersList?.childNodes Checking whether the string is not null and not blank: chatMessage?.isNotBlank() Force unwraps Sometimes, you will have to face a situation where you will be sure that the object will not be null at the time of accessing it. However, since you have declared nullable at the beginning, you will have to end up using force unwraps. Force unwraps have the syntax of !!. This means you have to fetch the value of the calling object, irrespective of it being nullable. We are explicitly reading the chatMessage value to pass its value in the callback. The following is the code: callback(chatMessage!!) Force unwraps are something we should avoid. We should only use them while dealing with interoperability issues. Otherwise, using them is basically nothing but throwing away Kotlin's beautiful features. Using the let function With the help of Lambda and extension functions, Kotlin is providing yet another powerful feature in the form of let functions. The let() function helps you execute a series of steps on the calling object. This is highly useful when you want to perform some code where the calling object is used multiple times and you want to avoid a null check every time. In the following code block, the forEach loop will only get executed if onlineUsersList is not null. We can refer to the calling object inside the let function using it: fun showOnlineUsers(data: Json) { val onlineUsersList = document.getElementById("onlineUsersList") onlineUsersList?.let { val usersList = data["usersList"] as? Array<String> usersList?.forEachIndexed { _, nickName -> it.appendChild(getUserListItem(nickName)) } } } Named parameter What if we told you that while calling, it's not mandatory to pass the parameter in the same sequence that is defined in the function signature? Believe us. With Kotlin's named parameter feature, it's no longer a constraint. Take a look at the following function that has a nickName parameter and the second parameter is message: private fun logMessageFromMe(nickName: String, message: String) { val onlineUsersList = document.getElementById("chatMessages") val li = document.create.li { div(classes = "sentMessages") { span(classes = "chatMessage") { +message } span(classes = "filledInitialsMe") { +getInitials(nickName) } } } onlineUsersList?.appendChild(li) } If you call a function such as logMessageForMe(mrssage,nickName), it will be a blunder. However, with Kotlin, you can call a function without worrying about the sequence of the parameter. The following is the code for this: fun showNewMessage(data: Json) { logMessage(message = data["message"] as String, nickName = data["nickName"] as String) } Note how the showNewMessage() function is calling it, passing message as the first parameter and nickName as the second parameter. Disconnecting a socket Whenever any user leaves the chat room, we will show other online users a message saying x user left. Socket.IO will send a notification to the server when any client disconnects. Upon receiving the disconnect, the event server will remove the user from the list, decrement the count of online users, and broadcast the event to all clients. The code can look something like this: socket.on("disconnect", { usersList.remove(socket.nicknameas String) numOfUsers = numOfUsers.dec() val userJoinedData = json(Pair("numOfUsers", numOfUsers), Pair("nickName", socket.nickname)) socket.broadcast.emit("user_left", userJoinedData) }) Now, it's the client's responsibility to show the message for that event on the UI. The client will listen to the event and the showUsersLeft function will be called from the ChatWindow class. The following code is used for receiving the user_left broadcast: socket.on("user_left", { data -> chatWindow.showUserLeft(data) }) The following displays the message with the nickname of the user who left the chat and the count of the remaining online users: fun showUserLeft(data: Json) { logListItem("${data["nickName"]} left") logListItem(getParticipantsMessage(data["numOfUsers"] as Int)) } Styling the page using CSS We saw how to build a chat application using Kotlin, but without showing the data on a beautiful UI, the user will not like the web app. We have used some simple CSS to give a rich look to the index.ejs page. The styling code is kept inside webapp/css/ styles.css. However, we have done everything so far entirely and exclusively in Kotlin. So, it's better we apply CSS using Kotlin as well. You may have already observed that there are a few mentions of classes. It's nothing but applying the CSS in a Kotlin way. Take a look at how we have applied the classes while making HTML tree elements using a DSL: fun showLogin() { val formContainer = document.getElementById("container") as HTMLDivElement val loginDiv = document.create.div { id = "loginDiv" h3(classes = "title") { +"Welcome to Kotlin Blueprints chat app" } input(classes = "nickNameInput") { id = "nickName" onInputFunction = onInput() maxLength = 16.toString() placeholder = "Enter your nick name" } button(classes = "loginButton") { +"Login" onClickFunction = onLoginButtonClicked() } } formContainer.appendChild(loginDiv) } We developed an entire chat application using Kotlin. If you liked this extract, read our book Kotlin Blueprints to build a REST API using Kotlin. Read More Top 4 chatbot development frameworks for developers How to build a basic server-side chatbot using Go 5 reasons to choose Kotlin over Java
Read more
  • 0
  • 0
  • 16740

article-image-how-to-build-weather-app-using-kotlin-for-javascript
Sugandha Lahoti
04 May 2018
19 min read
Save for later

How to build a weather app using Kotlin for JavaScript

Sugandha Lahoti
04 May 2018
19 min read
In this tutorial, we will be covering JavaScript from a browser perspective. We will create a single page web app that will show the weather forecast for seven days from the current date. The user will provide a ZIP code as input for which the weather will be displayed. We will display all the basic information about the weather on a given day. We believe in learning by doing practicals. Let's see the power of Kotlin from a browser perspective. [box type="shadow" align="" class="" width=""]This article is an excerpt from the book,  Kotlin Blueprints, written by Ashish Belagali, Hardik Trivedi, and Akshay Chordiya. This book is a practical guide to building industry-grade web, mobile, and desktop applications in Kotlin using frameworks such as Spring Boot and Node.js[/box] Conceptually, we will cover the following points while making a web app: Setting up a project to use Kotlin along with JavaScript Showing simple text using Kotlin code Interacting with Document Object Model (DOM) using Kotlin DSL and usage of kotlinx.html Creating your first Kotlin and JavaScript project Tighten your shoelaces! As a first step, we will do the setup and create a simple app that prints on a console and changes the background color of a page. Choosing an IDE From Microsoft Visual Studio, NetBeans to Eclipse and Code::Blocks, we have a series of great and powerful IDEs. Each of them has their own pros and cons. JetBrains is one of the giants that is famous for its cutting-edge software and IntelliJ IDEA Ultimate is considered among one of the most intelligent IDEs for Java. It supports Kotlin and JavaScript by default. There is no other hassle in setting up the environments. Just install it from https://www.jetbrains.com/idea and you are all set to create your first JavaScript project using Kotlin. Creating a project If you are all done with setting up an IDE, launch IntelliJ IDEA and select Create New Project. You will then have the following screen opened. Select Kotlin | Kotlin (JavaScript) options as shown in the following screenshot: Make sure you select Kotlin (JavaScript) as highlighted in the preceding screenshot. The next step is to provide your Project name and choose a destination for your project directory: Creating an HTML page No browser project is complete without an HTML page. Create an index.html page in the root directory of your project. And write the following lines in a <body> tag: <body> <script type="text/javascript" src="out/production/KotlinWeb/lib/kotlin.js"></script> <script type="text/javascript" src="out/production/KotlinWeb/KotlinWeb.js"></script> </body> Creating a Main.kt file After creating our index.html page. Let's create our first Kotlin file. Name it as Main.kt or provide any desired name. Create a file in the src folder and write the following function inside: fun main(args: Array<String>) { document.bgColor="FF0000" val message = "Kotlin Blueprints" println("Your first JS code using Kotlin") } Build the project, by selecting the Build | Build Project menu option. On expanding the project explorer on the left of your workspace you will have the following type of directory structure: Make sure you double-check that the <script> tags are added in the <body>. They should match the name with the files created inside out/production/KotlinBluePrintsJSDemo/. Running the project If you have followed all the steps simply execute your index.html file in any browser and you should see the following output on your console and a red colored page rendered on your DOM: Congratulations! You have executed your first Kotlin code on the browser. Since we have code written in Kotlin, source code needs to recompile every time we update the code. Simply reloading an HTML page will not work. So build your project from the Build | Build Project menu option. Developing a weather forecast web app It was fun writing Kotlin code for a browser and seeing it working, wasn't it? Now we should target bigger goals. Let's develop another app step by step. We will build a weather forecast app, where the user will enter a ZIP code and can see the weather details (seven-day forecast) for the provided region. We will use the OpenWeatherMap API to get the weather details. Please find more details at https://openweathermap.org/api. Before we move to the next step we should create a new project named KotlinBluePrintsJSDemo. Some quick steps to follow: Create a Kotlin+JavaScript project named KotlinBluePrintsJSDemo. Create an index.html page under the root directory. Create a Main.kt file inside the src directory. Add script tags to add two JavaScript files, kotlin.js and KotlinBluePrintsJSDemo.js. Build a project. We want to create an app that will look like this at the end. Entirely in Kotlin: Creating a UI with dummy data The very first thing we do is to create a dummy view and get a clear idea of how our HTML page will look. We will also use a bit of CSS to give basic styles to our <div> tags. Simple HTML approach Now we shall look at the index.html file that we created by writing the following code. It's boring plain HTML tags: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Kotlin BluePrints JS Demo</title> </head> <body> <link rel="stylesheet" type="text/css" href="css/main.css"> <div id="container"> <label>Enter zip code : <input id="zipCode" type="number"> </label> <button id="submitZipCode" type="button">Get Weather</button> <div class="weatherContainer"> <div class="weatherBlock"> <div>13 Oct, 2017</div> <img src="images/weather_img.png" height="40px" width="40px"> <div> <span>35</span> <span>20</span> </div> </div> <div class="weatherBlock"> <div>13 Oct, 2017</div> <img src="images/weather_img.png" height="40px" width="40px"> <div> <span>35</span> <span>20</span> </div> </div> <!-- Similarly you can have remaining divs here --> </div> </div> <script src="out/production/KotlinBluePrintsJSDemo/lib/kotlin.js"> </script> <script src="out/production/KotlinBluePrintsJSDemo /KotlinBluePrintsJSDemo.js"></script> </body> </html> Observe two tags, <script> and <link>. We haven't added CSS yet. Let's create a CSS folder under the root directory and create a main.css file inside. The main.css will contain the following code for now: .weatherContainer { width: 90%; background: #EEEEEE; margin: 10px auto; position: relative; text-align:center; } .weatherBlock { background: #FFFFFF; height: 100px; width: 100px; display:inline-block; margin: 10px; } In a source code, we have also created an images directory and put some weather images in it to make the UI more beautiful. Creating UI using Kotlin The index.html page contains all the HTML code. We need to now move that HTML code to Kotlin. Kotlin has the capability to manipulate the DOM element and it can also deal with the tree elements and their hierarchy. Simply put two <script> tags and a parent <div> tag in an HTML page and everything will go to a Kotlin page: <div id="container"> </div> Now, in Main.kt we will write the HTML code that we previously wrote inside index.html. Main.kt and it will look as follows: fun main(args: Array<String>) { createUserInput() } fun createUserInput() { val root = document.getElementById("container") root?.innerHTML = "<label>Enter zip code : <input id="zipCode" type="number"></label>" + "<button id="submitZipCode" type="button">Get Weather</button>" + "<div class="weatherContainer">" + "<div class="weatherBlock">" + "<div>13 Oct, 2017</div>" + "<img src="images/weather_img.png" height="40px" width="40px">"+ "<div>" + "<span>35</span>" + "<span>20</span>" + "</div>" + "</div>" + "<div class="weatherBlock">" + "<div>13 Oct, 2017</div>" + "<img src="images/weather_img.png" height="40px" width="40px">"+ "<div>" + "<span>35</span>" + "<span>20</span>" + "</div>" + "</div>" // Similarly add remaining divs } Take a note of the document object and its function getElementById. This is coming from the kotlin.browser.document package. Also org.w3c.dom as companion classes for all HTML elements. With object root, we get access to an innerHTML property and we can assign any valid HTML strings to it and it will get rendered. It is noteworthy that the nullability of root objects is handled with Null Safety operator ? of Kotlin. What is DSL? Now, the previous approach doesn't create much difference. Kotlin would want to do better! Let us introduce you to the beautiful concept of DSL. DSL stands for Domain Specific Language. As the name indicates, it gives you the feeling that you are writing code in a language, using terminology particular to a given domain, without being geeky, but then this terminology is cleverly embedded as a syntax in a powerful language. If you are from the Groovy community you must be aware of builders. Groovy builders allow defining data in a semi declarative way. It's a kind of mini-language of its own. Builders are considered good for generating XML and laying out UI components. Kotlin DSL uses Lambdas a lot. DSL in Kotlin are type-safe builders. It means we can detect compilation errors in IntelliJ's beautiful IDE. The type-check builders are much better than the dynamically-typed builders of Groovy. Using Kotlinx.html The DSL to build HTML trees is a pluggable dependency. We, therefore, need to set it up and configure it for our project. For now, we will keep things simple and add the dependency in them in the form of a .jar file. We will keep this .jar file in the lib folder, which will reside at the root level. The library is created by the JetBrains team only and it's open source. You can find it at https://github.com/Kotlin/kotlinx.html. You can simply visit the URL https://dl.bintray.com/kotlin/kotlinx.html/org/jetbrains/kotlinx/kotlinx-html-js/0.6.4/ and download the .jar file from there. For this demo app, we have used v 0.6.4. The .jar repository page can look as follows: To set up the kotlinx.html dependency in your app please follow these steps: In our app, we are using v 0.6.4. Make sure you download the JAR file named  kotlinx-html-js-0.6.4.jar. Please verify that you have kept the .jar file inside the lib directory. Also, do not forget to add the .jar file as a library. Right-click on the .jar file and select Add As Library…. Select classes as a category while adding them as a library. Or you can simply choose to add the dependency via Gradle, in that, you need to add the following things to your build.gradle file: repositories { jcenter() } dependencies { //Fill this in with the version of kotlinx in use in your project def kotlinx_html_version = "your_version_here" // include for client-side compile "org.jetbrains.kotlinx:kotlinx-html- js:${kotlinx_html_version}" } Refactoring the HTML code using DSL The DSL code to make a button with the title "Get Weather" looks as follows: button { +"Get Weather" type = ButtonType.button onClickFunction = { // Your code to handle button click goes here. } } Simple and clean code. Similarly, let's create a function that will display an entire div, which has a label, text input, and button: fun getInputDiv(): HTMLDivElement { val inputDiv = document.create.div { label { +"Enter zip code : " input { id = "zipCode" type = InputType.number value = 411021.toString() } } button { +"Get Weather" type = ButtonType.button onClickFunction = { // Your code to handle button click goes here } } } return inputDiv } Observe how we have provided ID, input types, and a default ZIP code value. A default ZIP code value is optional. Let's spend some time understanding the previous code. label, input, button, type, id, and onClickFunction are nothing but functions. They are basically Lambda functions. Some of the functions that use Lambda parameters and call variations can be as follows: someFunction({}) someFunction("KotlinBluePrints",1,{}) someFunction("KotlinBluePrints",1){} someFunction{} Let's run the code. You may get an error on the console saying: Error Uncaught Error: Error loading module 'KotlinBluePrintsJSDemo'. Its dependency 'kotlinx-html-js' was not found. Please, check whether 'kotlinx-html-js' is loaded prior to 'KotlinBluePrintsJSDemo'. This is because kotlinx-html-js is missing, which is required to process the DSL generated code. You can see the kotlinx-html-js file generated under the out/production/KotlinBluePrintsJSDemo/lib path. Calling a weather API Now it's time to get the weather data and display it on the page. We will use XMLHttpRequest to achieve this. Register yourself at http://openweathermap.org/appid and get your application ID. Your application ID will be appended to the actual URL to make the authenticated call to the weather API. Once you get the app ID let's keep that information in the Constants.kt file: const val IMAGE_URL = "http://openweathermap.org/img/w/%s.png" const val BASE_URL = "https://api.openweathermap.org/data/2.5/forecast/daily? mode=json&units=metric&cnt=7" const val APP_ID = "Your open weather map application id" const val FULL_URL = "$BASE_URL&appid=$APP_ID&q=" The Constants.kt file is not as simple as it looks. Check how we have stored different values. We have used const val, which is equivalent to const and static used combined. Also defining FULL_URL uses the concept of string interpolation. String interpolation is used to concatenate static strings along with string objects. You can also call functions in string interpolation as follows: h4 { +"Weather info for ${forecastResult.city.name}, (${forecastResult.city.country})" } Now, in onClickFunction we write the following code to perform the API call and on the successful response we call a showData function, which takes a forecastResult object: onClickFunction = { val zipCode = document.getElementById("zipCode") as HTMLInputElement val xmlHttpRequest = XMLHttpRequest() xmlHttpRequest.open("GET", FULL_URL + zipCode.value, false) xmlHttpRequest.send() println(xmlHttpRequest.responseText) val forecastResult = JSON.parse<ForecastResult> (xmlHttpRequest.responseText) showData(forecastResult) } Reading data from input elements See how we read data from input elements: document.getElementById("zipCode") as HTMLInputElement The as HTMLInputElement construct is basically casting a result into the HTMLInputElement class. Using as directly is not advisable because it can give you ClassCastException; a proper way to use it is as? HTMLInputElement. This returns null if the class cast fails. And Kotlin will force you to use a Null Safety operator from that very moment. Data classes We are maintaining ForecastResult, which is our model. For this purpose, we have data classes in Kotlin. One of the coolest features in Kotlin is data classes. All the pain that we used to endure to create and maintain POJO classes in Java is gone. No need to have those dedicated packages to hold your model class. Any Kotlin file can hold your data class. By default it provides you methods such as toString(), equals(), copy(), and hashCode() method implementation. In Android, we mostly use these types of classes to hold our JSON responses in the form of model classes. You can check out the data classes we created in ServerResponses.kt: data class ForecastResult(val city: City, val list: Array<Forecast>) data class City(val id: Long, val name: String, val coord: Coordinates, val country: String, val population: Int) data class Coordinates(val lon: Float, val lat: Float) data class Forecast(val dt: Long, val temp: Temperature, val pressure: Float, val humidity: Int, val weather: Array<Weather>, val speed: Float, val deg: Int, val clouds: Int) data class Temperature(val day: Float, val min: Float, val max: Float, val night: Float, val eve: Float, val morn: Float) data class Weather(val id: Long, val main: String, val description: String, val icon: String) Some of the points to consider while using data classes are: The primary constructor needs to have at least one parameter All primary constructor parameters need to be marked as val or var Data classes cannot be abstract, open, sealed, or inner (Before version 1.1) data classes may only implement interfaces Showing data to the user Now comes the interesting part. We gate a ForecastResult object, which holds all the records. The list object holds records for seven days. Let's create a showData function that takes a ForecastResult object and display title text in <h4>.  The code will look like the following snippet. Also, it has yet again one more example of string interpolation: fun showData(forecastResult: ForecastResult) { val root = document.getElementById("container") root?.appendChild(document.create.div(classes = "currentTemp") { h4 { +"Weather info for ${forecastResult.city.name (${forecastResult.city.country})" } }) } This is simple now, quickly create a showForecast function that will be called from showData and will display the weather forecast for seven days. The showForecast is used with a function from Kotlin.  thewith() is one of those functions that is liked by the developer community a lot; it makes use of Kotlin sweeter. The with() function accepts the receiver and the code written inside the function automatically applies to the receiver object. It's an inline function. Check out the following document: /** * Calls the specified function [block] with the given [receiver] as its receiver and returns its result. */ public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block() In the code, observe how each iteration is using a with block. We have removed some of the lines from the original code, so that we can have the clean code snippet here: forecastResult.list.forEachIndexed { index, forecast -> with(forecast) { weatherContainer.appendChild(document.create.div(classes = "weatherBlock") { div { p(classes = "currentTemp") { +"${Math.round(temp.day)} °C" } } img(classes = "weatherImage") { src = "images/weather_img.png" } div { span(classes = "secondaryText") { +weather[0].main } } div { with(temp) { span(classes = "primaryText") { +"${Math.round(max)} °C" } span(classes = "secondaryText") { +" /${Math.round(min)} °C" } } } onClickFunction = { showDetailedForecast(forecastResult.city, forecast) } }) } } DSL and Kotlin code are now beautifully gelled. Also, notice the onClickFunction that we wrote on div.  Sweet, isn't it? Showing weather details A very small part of the app is left now. Let's show some more details to the user. Along with this, we will also learn a few more features of Kotlin. We have created a showDetailedForecast function that takes the City and Forecast objects as parameters. The following code snippets provide two things to learn: fun showDetailedForecast(city: City, forecast: Forecast) { val root = document.getElementById("container") val weatherDetailDiv = document.create.div(classes = "detailsContainer") val basicDetailDiv = document.create.div { p(classes = "secondaryText") { +"${city.name}, ${city.country} (${city.coord.lat},${city.coord.lon})" } p(classes = "secondaryText") { +forecast.dt.getFullDate() } p(classes = "secondaryText") { +"${forecast.weather[0].main}, ${forecast.weather[0].description}" } } val otherDetailsDiv = document.create.div { div { id = "leftDiv" span(classes = "currentTemp") { +"${Math.round(forecast.temp.day)} °C" } img { src = "images/weather_img.png" width = 90.toString() height = 90.toString() } } div { id = "rightDiv" p(classes = "secondaryText") { +"Pressure: ${forecast.pressure} mb" } p(classes = "secondaryText") { +"Humidity: ${forecast.humidity} %" } p(classes = "secondaryText") { +"Wind: ${forecast.speed} mph" } p(classes = "secondaryText") { +"Cloudiness: ${forecast.clouds} %" } } div(classes = "clearBoth") } weatherDetailDiv.appendChild(basicDetailDiv) weatherDetailDiv.appendChild(otherDetailsDiv) root?.appendChild(weatherDetailDiv) } Named parameters In Kotlin, we can call/bind a parameter with their name for any function. We can call the preceding function by interchanging the parameter sequence as well. Something like the following: showDetailedForecast(forecast = forecast, city = forecastResult.city) Observe that we swapped the place of the variable. And no wonder, all CSS classes that we have applied so far have a named parameter. Check all previous <div>, <h>, and <p> tags. Consider the following examples: val weatherDetailDiv = document.create.div(classes = "detailsContainer") button(classes = "getWeatherButton") span(classes = "primaryText") { +"${Math.round(max)} °C" } Extension functions Extension functions are a beautiful feature of Kotlin. Extension functions allow us to add the functions in the native class sets. All extension functions are statically resolved. Check out DateExtension.kt, it has three extension functions written for Long objects. They return different date formats. The code inside it may look a bit strange, which we will discuss in the following section: fun Long.getShortDate(): String { val getFormattedDate: dynamic = js("window.getShortDate") return getFormattedDate(this) } fun Long.getFullDate(): String { val getFormattedDate: dynamic = js("window.getFullDate") return getFormattedDate(this) } fun Long.getFullWeekDay(): String { val getFormattedDate: dynamic = js("window.getFullWeekDay") return getFormattedDate(this) } We don't need to write utility methods in Kotlin. We should prefer extension functions over Utils. Do not try to have any heavy methods as extension functions, instance functions are always good. Writing extension functions to format dates and to have some validation functions is OK. But it's not good to write an API calling function for any string class. Remember they are statically resolved. A project loaded with static is not good for memory. Giving final touches We wrote many lines of code so far. We also refactored them periodically. Once again it's a time to refactor and look for the possible improvements. Let's take a look back and see if there is any possibility of refactoring the code further. Adding CSS Let's add some custom font and style some of the missed HTML elements. We have used Robot font, you can use any font of your desire. It's a simple one-liner code to mention the font in the app. Add the following line to your index.html page just after the <body> tag: <link href="https://fonts.googleapis.com/css? family=Roboto+Condensed" rel="stylesheet"> And in main.css apply the font to an entire HTML page: html * { font-family: 'Roboto Condensed', sans-serif; } Reload the page. Looks beautiful now, doesn't it? To summarize, we learned various elements of Kotlin such as setting up Kotlin for JavaScript projects, interacting with DOM elements, DSL, and so on. The purpose of this article was to show that Kotlin's support for JavaScript is no more an experiment. It's already production ready. You can see what can be done using the benefits of statically typed programming languages and powerful JavaScript ecosystems. To know more about how to use Kotlin code for writing a Node.js application, you may refer to this book Kotlin Blueprints. Build your first Android app with Kotlin How to convert Java code into Kotlin 5 application development tools that will matter in 2018  
Read more
  • 0
  • 0
  • 7259
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-how-android-app-developers-can-convert-iphone-apps
Michael Kordvani
02 May 2018
5 min read
Save for later

How Android app developers can convert iPhone apps

Michael Kordvani
02 May 2018
5 min read
Businesses like to cast their nets as wide as possible in search of new customers. This type of broad outreach requires designing mobile apps for both iOS and Android phones. Although iPhones are very popular in the U.S. market, if you want to step up and attract global customers, you need to expand your product to the Android platform. Most Android app developers will face this challenge at some point: how to create an Android app from an iPhone app, and make it at least as successful as the primary product. It's not surprising that developers tend to concentrate on building up their skills for one platform in particular. Both platforms have their challenges. Spreading yourself too thin in an effort to meet the requirements for both phones can mean that the user experience suffers. But the challenges can be overcome. iPhone apps are great, but limited in terms of market size. Android apps are the biggest market players, and companies often ask the same team of Android app developers to take on both projects at once. With a few tips and tricks to help you along, you’ll be able to make your project a success. What are the benefits of redesigning an iPhone App into an Android App? Before converting your iPhone app into an Android app, it’s important to keep in mind that enlarging the customer base is not the only benefit. You will also get the chance to add more features, diversify money-making methods with new options for in-app purchasing and advertisements, as well as get a full product overhaul at only a fraction of the cost of starting from scratch. These are the obvious reasons why companies usually don’t overlook the possibility of iPhone app conversion. When a company has a team of iPhone and Android app developers and can save on new projects, it often pays off handsomely in the end. Hiring a product manager to oversee the process is not a bad idea if you have the budget for it. A manager can help the team understand the similar elements of these otherwise different platforms. Despite the UX/UI design differences in terms of navigation, icons and app architecture, you still need to code with customer requirements in mind. Also, before you start redesigning the product, keep in mind that the business model may need to be tweaked and the store submission process is quite different. UX and UI design differences between Android and iOS The platforms have significant differences in terms of design. You cannot simply copy the elements from an iPhone to an Android phone environment, at least not in a clear-cut way. You must design with the already-set styles in mind. For example, Android apps use a specific icon library, which is different from the one used for iOS. Android app developers and designers work with a wider color palette, varying in nuances and shades, while iPhone apps are more standardized. Roboto is the preferred Android font, and San Francisco is its iPhone counterpart. The hierarchical typography is not the same either. Because of the variations in the navigation tools, the user interface looks very different on Android phones. iPhone navigation is concentrated at the bottom; Android phones use more side and top navigation bars. Don’t forget about the thumb issue. iPhones are generally built around an average-sized thumb. With Android, you have a bit more leeway to accommodate all thumb sizes. Even if you focus only on these design basics, the user interface on an iPhone will still look different than the one on an Android smartphone. If we factor in button styles (flat on iOS vs. flat/floating on Android), grids and action sheets, as well as dropdown menus, things get even more complex. This guide offers a helpful comparison overview you can use when converting iPhone apps into Android apps. Sizing and resolution on Android phones also present their own challenges. Designers need to include different Android screen resolutions, which is already significantly more challenging than designing for the unified iPhone layout. iPhone app developers use points, and Android app developers use pixels when measuring screen objects, such as fonts and icons. The pt/px ratio is 0.75. At the same time, clients need some degree of standardization for brand recognition. They don’t want to confuse users with two apps that don’t appear to be from the same company. Further considerations Android app developers need to make about code and external libraries It can be challenging to find a team of Android app developers who also know how to code in iOS-friendly languages. However, it may be more efficient and cost-effective than working with two different teams. Programming languages that work for both Android apps and iOS apps are Kotlin and C-languages. Nonetheless, both platforms have widely preferred languages: Swift for iPhone apps and Java for Android apps. Android app developers should also check for compatibility before using external libraries and tools in the conversion project. Although challenging, converting iPhone apps for the Android OS platform is far from impossible. After all, people do it every day, as dual-platform apps are the rule rather than the exception. All you need to do to make a great product is to understand the key differences and make the necessary adjustments. Build your first Android app with Kotlin How to Secure and Deploy an Android App Why are Android developers switching from Java to Kotlin?
Read more
  • 0
  • 0
  • 2961

article-image-how-to-secure-and-deploy-an-android-app
Sugandha Lahoti
20 Apr 2018
17 min read
Save for later

How to Secure and Deploy an Android App

Sugandha Lahoti
20 Apr 2018
17 min read
In this article, we will be covering two extremely important Android-related topics: Android application security Android application deployment We will kick off the post by discussing Android application security. Securing an Android application It should come as no surprise that security is an important consideration when building software. Besides the security measures put in place in the Android operating system, it is important that developers pay extra attention to ensure that their applications meet the set security standards. In this section, a number of important security considerations and best practices will be broken down for your understanding. Following these best practices will make your applications less vulnerable to malicious programs that may be installed on a client device. Data storage All things being equal, the privacy of data saved by an application to a device is the most common security concern in developing an Android application. Some simple rules can be followed to make your application data more secure. Securing your data when using internal storage As we saw in the previous chapter, internal storage is a good way to save private data on a device. Every Android application has a corresponding internal storage directory in which private files can be created and written to. These files are private to the creating application, and as such cannot be accessed by other applications on the client device. As a rule of thumb, if data should only be accessible by your application and it is possible to store it in internal storage, do so. Feel free to refer to the previous chapter for a refresher on how to use internal storage. Securing your data when using external storage External storage files are not private to applications, and, as such, can be easily accessed by other applications on the same client device. As a result of this, you should consider encrypting application data before storing it in external storage. There are a number of libraries and packages that can be used to encrypt data prior to its saving to external storage. Facebook's Conceal (http://facebook.github.io/conceal/) library is a good option for external-storage data encryption. In addition to this, as another rule of thumb, do not store sensitive data in external storage. This is because external storage files can be manipulated freely. Validation should also be performed on input retrieved from external storage. This validation should be done as a result of the untrustworthy nature of data stored in external storage. Securing your data when using internal storage. Content providers can either prevent or enable external access to your application data. Use the android:exported attribute when registering your content provider in the manifest file to specify whether external access to the content provider should be permitted. Set android:exported to true if you wish the content provider to be exported, otherwise set the attribute to false. In addition to this, content provider query methods—for example, query(), update(), and delete()—should be used to prevent SQL injection (a code injection technique that involves the execution of malicious SQL statements in an entry field by an attacker). Networking security Best practices for your Android App development There are a number of best practices that should be followed when performing network transactions via an Android application. These best practices can be split into different categories. We shall speak about Internet Protocol (IP) networking and telephony networking best practices in this section. IP networking When communicating with a remote computer via IP, it is important to ensure that your application makes use of HTTPs wherever possible (thus wherever it is supported in the server). One major reason for doing this is because devices often connect to insecure networks, such as public wireless connections. HTTPs ensure encrypted communication between clients and servers, regardless of the network they are connected to. In Java, an HttpsURLConnection can be used for secure data transfer over a network. It is important to note that data received via an insecure network connection should not be trusted. Telephony networking In instances where data needs to be transferred freely across a server and client applications, Firebase Cloud Messaging (FCM)—along with IP networking—should be utilized instead of other means, such as the Short Messaging Service (SMS) protocol. FCM is a multi-platform messaging solution that facilitates the seamless and reliable transfer of messages between applications. SMS is not a good candidate for transferring data messages, because: It is not encrypted It is not strongly authenticated Messages sent via SMS are subject to spoofing SMS messages are subject to interception Input validation The validation of user input is extremely important in order to avoid security risks that may arise. One such risk, as explained in the Using content providers section, is SQL injection. The malicious injection of SQL script can be prevented by the use of parameterized queries and the extensive sanitation of inputs used in raw SQL queries. In addition to this, inputs retrieved from external storage must be appropriately validated because external storage is not a trusted data source. Working with user credentials The risk of phishing can be alleviated by reducing the requirement of user credential input in an application. Instead of constantly requesting user credentials, consider using an authorization token. Eliminate the need for storing usernames and passwords on the device. Instead, make use of a refreshable authorization token. Code obfuscation Before publishing an Android application, it is imperative to utilize a code obfuscation tool, such as ProGuard, to prevent individuals from getting unhindered access to your source code by utilizing various means, such as decompilation. ProGuard is prepackaged included within the Android SDK, and, as such, no dependency inclusion is required. It is automatically included in the build process if you specify your build type to be a release. You can find out more about ProGuard here: https://www.guardsquare.com/en/proguard . Securing broadcast receivers By default, a broadcast receiver component is exported and as a result can be invoked by other applications on the same device. You can control access of applications to your apps's broadcast receiver by applying security permissions to it. Permissions can be set for broadcast receivers in an application's manifest file with the <receiver> element. Securing your Dynamically loading code In scenarios in which the dynamic loading of code by your application is necessary, you must ensure that the code being loaded comes from a trusted source. In addition to this, you must make sure to reduce the risk of tampering code at all costs. Loading and executing code that has been tampered with is a huge security threat. When code is being loaded from a remote server, ensure it is transferred over a secure, encrypted network. Keep in mind that code that is dynamically loaded runs with the same security permissions as your application (the permissions you defined in your application's manifest file). Securing services Unlike broadcast receivers, services are not exported by the Android system by default. The default exportation of a service only happens when an intent filter is added to the declaration of a service in the manifest file. The android:exported attribute should be used to ensure services are exported only when you want them to be. Set android:exported to true when you want a service to be exported and false otherwise. Deploying your Android Application So far, we have taken an in-depth look at the Android system, application development in Android, and some other important topics, such as Android application security. It is time for us to cover our final topic for this article pertaining to the Android ecosystem—launching and publishing an Android application. You may be wondering at this juncture what the words launch and publish mean. A launch is an activity that involves the introduction of a new product to the public (end users). Publishing an Android application is simply the act of making an Android application available to users. Various activities and processes must be carried out to ensure the successful launch of an Android application. There are 15 of these activities in all. They are: Understanding the Android developer program policies Preparing your Android developer account Localization planning Planning for simultaneous release Testing against the quality guideline Building a release-ready APK Planning your application's Play Store listing Uploading your application package to the alpha or beta channel Device compatibility definition Pre-launch report assessment Pricing and application distribution setup Distribution option selection In-app products and subscriptions setup Determining your application's content rating Publishing your application Wow! That's a long list. Don't fret if you don't understand everything on the list. Let's look at each item in more detail. Understanding the Android developer program policies There is a set of developer program policies that were created for the sole purpose of making sure that the Play Store remains a trusted source of software for its users. Consequences exist for the violation of these defined policies. As a result, it is important that you peruse and fully understand these developer policies—their purposes and consequences—before continuing with the process of launching your application. Preparing your Android developer account You will need an Android developer account to launch your application on the Play Store. Ensure that you set one up by signing up for a developer account and confirming the accuracy of your account details. If you ever need to sell products on an Android application of yours, you will need to set up a merchant account. Localization planning Sometimes, for the purpose of localization, you may have more than one copy of your application, with each localized to a different language. When this is the case, you will need to plan for localization early on and follow the recommended localization checklist for Android developers. You can view this checklist here: https://developer.android.com/distribute/best-practices/launch/localization-checklist.html. Planning for simultaneous release You may want to launch a product on multiple platforms. This has a number of advantages, such as increasing the potential market size of your product, reducing the barrier of access to your product, and maximizing the number of potential installations of your application. Releasing on numerous platforms simultaneously is generally a good idea. If you wish to do this with any product of yours, ensure you plan for this well in advance. In cases where it is not possible to launch an application on multiple platforms at once, ensure you provide a means by which interested potential users can submit their contact details so as to ensure that you can get in touch with them once your product is available on their platform of choice. Testing against the quality guidelines Quality guidelines provide testing templates that you can use to confirm that your application meets the fundamental functional and non-functional requirements that are expected by Android users. Ensure that you run your applications through these quality guides before launch. You can access these application quality guides here: https://developer.android.com/develop/quality-guidelines/index.html. Building a release-ready application package (APK) A release-ready APK is an Android application that has been packaged with optimizations and then built and signed with a release key. Building a release-ready APK is an important step in the launch of an Android application. Pay extra attention to this step. Planning your application's Play Store listing This step involves the collation of all resources necessary for your product's Play Store listing. These resources include, but are not limited to, your application's log, screenshots, descriptions, promotional graphics, and videos, if any. Ensure you include a link to your application's privacy policy along with your application's Play Store listing. It is also important to localize your application's product listing to all languages that your application supports. Uploading your application package to the alpha or beta channel As testing is an efficient and battle-tested way of detecting defects in software and improving software quality, it is a good idea to upload your application package to alpha and beta channels to facilitate carrying out alpha and beta software testing on your product. Alpha testing and beta testing are both types of acceptance testing. Device compatibility definition This step involves the declaration of Android versions and screen sizes that your application was developed to work on. It is important to be as accurate as possible in this step as defining inaccurate Android versions and screen sizes will invariably lead to users experiencing problems with your application. Pre-launch report assessment Pre-launch reports are used to identify issues found after the automatic testing of your application on various Android devices. Pre-launch reports will be delivered to you, if you opt in to them, when you upload an application package to an alpha or beta channel. Pricing and application distribution setup First, determine the means by which you want to monetize you application. After determining this, set up your application as either a free install or a paid download. After you have set up the desired pricing of your application, select the countries you wish to distribute you applications to. Distribution option selection This step involves the selection of devices and platforms—for example, Android TV and Android Wear—that you wish to distribute your app on. After doing this, the Google Play team will be able to review your application. If your application is approved after its review, Google Play will make it more discoverable. In-app products and subscriptions setup If you wish to sell products within your application, you will need to set up your in-app products and subscriptions. Here, you will specify the countries that you can sell into and take care of various monetary-related issues, such as tax considerations. In this step, you will also set up your merchant account. Determining your application's content rating It is necessary that you provide an accurate rating for the application you are publishing to the Play Store. This step is mandated by the Android Developer Program Policies for good reason. It aids the appropriate age group you are targeting to discover your application. Publishing your application Once you have catered for the necessary steps prior to this, you are ready to publish your application to the production channel of the Play Store. Firstly, you will need to roll out a release. A release allows you to upload the APK files of your application and roll out your application to a specific track. At the end of the release procedure, you can publish your application by clicking Confirm rollout. So, that was all we need to know to publish a new application on the Play Store. In most cases, you will not need to follow all these steps in a linear manner, you will just need to follow a subset of the steps—more specifically, those pertaining to the type of application you wish to publish. Releasing your Android app Having signed your  application, you can proceed with completing the required application details toward the goal of releasing your app. Firstly, you need to create a suitable store listing for the application. Open the application  in the Google Play Console and navigate to the store-listing page (this can be done by selecting Store Listing on the side navigation bar). You will need to fill out all the required information in the store listing page before we proceed further. This information includes product details, such as a title, short description, full description, as well as graphic assets and categorization information—including the application type, category and content rating, contact details, and privacy policy. The Google Play Console store listing page is shown in the following screenshot: Once the store listing information has been filled in, the next thing to fill in is the pricing and distribution information. Select Pricing & distribution on the left navigation bar to open up its preference selection page. For the sake of this demonstration, we set the pricing of this app to FREE. We also selected five random countries to distribute this application to. These countries are Nigeria, India, the United States of America, the United Kingdom, and Australia: Besides selecting the type of pricing and the available countries for product distribution, you will need to provide additional preference information. The necessary information to be provided includes device category information, user program information, and consent information. It is now time to add our signed APK to our Google Play Console app. Navigate to App releases | MANAGE BETA | EDIT RELEASE. In the page that is presented to you, you may be asked whether you want to opt into Google play app signing: For the sake of this example, select OPT-OUT. Once OPT-OUT is selected, you will be able to choose your APK file for upload from your computer's file system. Select your APK for upload by clicking BROWSE FILES, as shown in the following screenshot: After selecting an appropriate APK, it will be uploaded to the Google Play Console. Once the upload is done, the play console will automatically add a suggested release name for your beta release. This release name is based on the version name of the uploaded APK. Modify the release name if you are not comfortable with the suggestion. Next, add a suitable release note in the text field provided. Once you are satisfied with the data you have input, save and continue by clicking the Review button at the bottom of the web page. After reviewing the beta release, you can roll it out if you have added beta testers to your app. Rolling out a beta release is not our focus, so let's divert back to our main goal: publishing the Messenger app. Having uploaded an APK for your application, you can now complete the mandatory content rating questionnaire. Click the Content rating navigation item on the sidebar and follow the instructions to do this. Once the questionnaire is complete, appropriate ratings for your application will be generated: With the completion of the content rating questionnaire, the application is ready to be published to production. Applications that are published to production are made available to all users on the Google Play Store. On the play console, navigate to App releases | Manage Production | Create releases. When prompted to upload an APK, click the ADD APK FROM LIBRARY button to the right of the screen and select the APK we previously uploaded (the APK with a version name of 1.0) and complete the necessary release details similar to how we did when creating a beta release. Click the review button at the bottom of the page once you are ready to proceed. You will be given a brief release summary in the page that follows: Go through the information presented in the summary carefully. Start the roll out to production once you have asserted that you are satisfied with the information presented to you in the summary. Once you start the roll out to production, you will be prompted to confirm your understanding that your app will become available to users of the Play Store: Click Confirm once you are ready for the app to go live on the Play Store. Congratulations! You have now published your first application to the Google Play Store! In this article, we learned how to secure and publish Android applications to the Google Play Store. We identified security threats to Android applications and fully explained ways to alleviate them, we also noted best practices to follow when developing applications for the Android ecosystem.  Finally, we took a deep dive into the process of application publication to the Play Store covering all the necessary steps for the successful publication of an Android application. You enjoyed an excerpt from the book, Kotlin Programming By Example, written by Iyanu Adelekan. This book will take on Android development with Kotlin, from building a classic game Tetris to a messenger app, a level up in terms of complexity. Build your first Android app with Kotlin Creating a custom layout implementation for your Android app  
Read more
  • 0
  • 0
  • 5238

article-image-getting-started-with-kotlin-programming
Sugandha Lahoti
19 Apr 2018
14 min read
Save for later

Getting started with Kotlin programming

Sugandha Lahoti
19 Apr 2018
14 min read
Learning a programming language is a daunting experience for many people and not one that most individuals generally choose to undertake. Regardless of the problem domain that you may wish to build solutions for, be it application development, networking, or distributed systems, Kotlin programming is a good choice for the development of systems to achieve the required solutions. In other words, a developer can't go wrong with learning Kotlin.  In this article, you will learn the following: The fundamentals of the Kotlin programming language The installation of Kotlin Compiling and running Kotlin programs Working with an IDE Kotlin is a strongly-typed, object-oriented language that runs on the Java Virtual Machine (JVM) and can be used to develop applications in numerous problem domains. In addition to running on the JVM, Kotlin can be compiled to JavaScript, and as such, is an equally strong choice for developing client-side web applications. Kotlin can also be compiled directly into native binaries that run on systems without a virtual machine via Kotlin/Native. The Kotlin programming language was primarily developed by JetBrains – a company based in Saint Petersburg, Russia. The developers at JetBrains are the current maintainers of the language. Kotlin was named after Kotlin island – an island near Saint Petersburg. Kotlin was designed for use in developing industrial-strength software in many domains but has seen the majority of its users come from the Android ecosystem. At the time of writing this post, Kotlin is one of the three languages that have been declared by Google as an official language for Android. Kotlin is syntactically similar to Java. As a matter of fact, it was designed to be a better alternative to Java. As a consequence, there are numerous significant advantages to using Kotlin instead of Java in software development.  Getting started with Kotlin In order to develop the Kotlin program, you will first need to install the Java Runtime Environment (JRE) on your computer. The JRE can be downloaded prepackaged along with a Java Development Kit (JDK). For the sake of this installation, we will be using the JDK. The easiest way to install a JDK on a computer is to utilize one of the JDK installers made available by Oracle (the owners of Java). There are different installers available for all major operating systems. Releases of the JDK can be downloaded from http://www.oracle.com/technetwork/java/javase/downloads/index.html: Clicking on the JDK download button takes you to a web page where you can download the appropriate JDK for your operating system and CPU architecture. Download a JDK suitable for your computer and continue to the next section: JDK installation In order to install the JDK on your computer, check out the necessary installation information from the following sections, based on your operating system. Installation on Windows The JDK can be installed on Windows in four easy steps: Double-click the downloaded installation file to launch the JDK installer. Click the Next button in the welcome window. This action will lead you to a window where you can select the components you want to install. Leave the selection at the default and click Next. The following window prompts the selection of the destination folder for the installation. For now, leave this folder as the default (also take note of the location of this folder, as you will need it in a later step). Click Next. Follow the instructions in the upcoming windows and click Next when necessary. You may be asked for your administrator's password, enter it when necessary. Java will be installed on your computer. After the JDK installation has concluded, you will need to set the JAVA_HOME environment variable on your computer. To do this: Open your Control Panel. Select Edit environment variable. In the window that has opened, click the New button. You will be prompted to add a new environment variable. Input JAVA_HOME as the variable name and enter the installation path of the JDK as the variable value. Click OK once to add the environment variable. Installation on macOS In order to install the JDK on macOS, perform the following steps: Download your desired JDK .dmg file. Locate the downloaded .dmg file and double-click it. A finder window containing the JDK package icon is opened. Double-click this icon to launch the installer. Click Continue on the introduction window. Click Install on the installation window that appears. Enter the administrator login and password when required and click Install Software. The JDK will be installed and a confirmation window displayed. Installation on Linux Installation of the JDK on Linux is easy and straightforward using apt-get: Update the package index of your computer. From your terminal, run: sudo apt-get update Check whether Java is already installed by running the following: java -version You'll know Java is installed if the version information for a Java install on your system is printed. If no version is currently installed, run: sudo apt-get install default-jdk That's it! The JDK will be installed on your computer. Compiling Kotlin programs Now that we have the JDK set up and ready for action, we need to install a means to actually compile and run our Kotlin programs. Kotlin programs can be either compiled directly with the Kotlin command-line compiler or built and run with the Integrated Development Environment (IDE). Working with the command-line compiler The command-line compiler can be installed via Homebrew, SDKMAN!, and MacPorts. Another option for setting up the command-line compiler is by manual installation. Installing the command-line compiler on macOS The Kotlin command-line compiler can be installed on macOS in various ways. The two most common methods for its installation on macOS are via Homebrew and MacPorts. Homebrew Homebrew is a package manager for the macOS systems. It is used extensively for the installation of packages required for building software projects. To install Homebrew, locate your macOS terminal and run: /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" You will have to wait a few seconds for the download and installation of Homebrew. After installation, check to see whether Homebrew is working properly by running the following command in your terminal: brew -v If the current version of Homebrew installed on your computer is printed out in the terminal, Homebrew has been successfully installed on your computer. After properly installing Homebrew, locate your terminal and execute the following command: brew install kotlin Wait for the installation to finish, after which you are ready to compile Kotlin programs with the command-line compiler. MacPorts Similar to HomeBrew, MacPorts is a package manager for macOS. Installing MacPorts is easy. It can be installed on a system by: Installing Xcode and the Xcode command-line tools. Agreeing to the Xcode license. This can be done in the terminal by running xcodebuild -license. Installing the required version of MacPorts. MacPort versions can be downloaded from https://www.macports.org/install.php. Once downloaded, locate your terminal and run port install kotlin as the superuser: sudo port install kotlin Installing the command-line compiler on Linux Linux users can easily install the command-line compiler for Kotlin with SDKMAN! SDKMAN! This can be used to install packages on Unix-based systems such as Linux and its various distributions, for example, Fedora and Solaris. SDKMAN! can be installed in three easy steps: Download the software on to your system with curl. Locate your terminal and run: curl -s "https://get.sdkman.io" | bash After you run the preceding command, a set of instructions will come up in your terminal. Follow these instructions to complete the installation. Upon completing the instructions, run: source "$HOME/.sdkman/bin/sdkman-init.sh" Run the following: sdk version If the version number of SDKMAN! just installed is printed in your terminal window, the installation was successful. Now that we have SDKMAN! successfully installed on our system, we can install the command-line compiler by running: sdk install kotlin Installing the command-line compiler on Windows In order to use the Kotlin command-line compilers on Windows: Download a GitHub release of the software from https://github.com/JetBrains/kotlin/releases/tag/v1.2.30 Locate and unzip the downloaded file Open the extracted kotlincbin folder Start the command prompt with the folder path You can now make use of the Kotlin compiler from your command line. Running your first Kotlin program Now that we have our command-line compiler set up, let's try it out with a simple Kotlin program. Navigate to your home directory and create a new file named Hello.kt. All Kotlin files have a .kt extension appended to the end of the filename. Open the file you just created in a text editor of your choosing and input the following: // The following program prints Hello world to the standard system output. fun main (args: Array<String>) { println("Hello world!") } Save the changes made to the program file. After the changes have been saved, open your terminal window and input the following command: kotlinc hello.kt -include-runtime -d hello.jar The preceding command compiles your program into an executable, hello.jar. The -include- runtime flag is used to specify that you want the compiled JAR to be self-contained. By adding this flag to the command, the Kotlin runtime library will be included in your JAR. The -d flag specifies that, in this case, we want the output of the compiler to be called. Now that we have compiled our first Kotlin program, we need to run it—after all, there's no fun in writing programs if they can't be run later on. Open your terminal, if it's not already open, and navigate to the directory where the JAR was saved to (in this case, the home directory).  To run the compiled JAR, perform the following: java -jar hello.jar After running the preceding command, you should see Hello world! printed on your display. Congratulations, you have just written your first Kotlin program! Writing scripts with Kotlin As previously stated, Kotlin can be used to write scripts. Scripts are programs that are written for specific runtime environments for the common purpose of automating the execution of tasks. In Kotlin, scripts have the .kts file extension appended to the file name. Writing a Kotlin script is similar to writing a Kotlin program. In fact, a script written in Kotlin is exactly like a regular Kotlin program! The only significant difference between a Kotlin script and regular Kotlin program is the absence of a main function. Create a file in a directory of your choosing and name it NumberSum.kts. Open the file and input the following program: val x: Int = 1 val y: Int = 2 val z: Int = x + y println(z) As you've most likely guessed, the preceding script will print the sum of 1 and 2 to the standard system output. Save the changes to the file and run the script: kotlinc -script NumberSum.kts A significant thing to take note of is that a Kotlin script does not need to be compiled. Using the REPL REPL is an acronym that stands for Read–Eval–Print Loop. An REPL is an interactive shell environment in which programs can be executed with immediate results given. The interactive shell environment can be invoked by running the kotlinc command without any arguments. The Kotlin REPL can be started by running kotlinc in your terminal. If the REPL is successfully started, a welcome message will be printed in your terminal followed by >>> on the next line, alerting us that the REPL is awaiting input. Now you can type in code within the terminal, as you would in any text editor, and get immediate feedback from the REPL. This is demonstrated in the following screenshot: In the preceding screenshot, the 1 and 2 integers are assigned to x and y, respectively. The sum of x and y is stored in a new z variable and the value held by z is printed to the display with the print() function. Working with an IDE Writing programs with the command line has its uses, but in most cases, it is better to use software built specifically for the purpose of empowering developers to write programs. This is especially true in cases where a large project is being worked on. An IDE is a computer application that hosts a collection of tools and utilities for computer programmers for software development. There are a number of IDEs that can be used for Kotlin development. Out of these IDEs, the one with the most comprehensive set of features for the purpose of developing Kotlin applications is IntelliJ IDEA. As IntelliJ IDEA is built by the creators of Kotlin, there are numerous advantages in using it over other IDEs, such as an unparalleled feature set of tools for writing Kotlin programs, as well as timely updates that cater to the newest advancements and additions to the Kotlin programming language. Installing IntelliJ IDEA IntelliJ IDEA can be downloaded for Windows, macOS, and Linux directly from JetBrains' website: https://www.jetbrains.com/idea/download. On the web page, you are presented with two available editions for download: a paid Ultimate edition and a free Community edition. The Community edition is sufficient if you wish to run the programs in this chapter. Select the edition you wish to download: Once the download is complete, double-click on the downloaded file and install it on your operating system as you would any program. Setting up a Kotlin project with IntelliJ The process of setting up a Kotlin project with IntelliJ is straightforward: Start the IntelliJ IDE application. Click Create New Project. Select Java from the available project options on the left-hand side of the newly opened window. Add Kotlin/JVM as an additional library to the project. Pick a project SDK from the drop-down list in the window. Click Next. Select a template if you wish to use one, then continue to the next screen. Provide a project name in the input field provided. Name the project HelloWorld for now. Set a project location in the input field. Click Finish. Your project will be created and you will be presented with the IDE window: To the left of the window, you will immediately see the project view. This view shows the logical structure of your project files. Two folders are present. These are: .idea: This contains IntelliJ's project-specific settings files. src: This is the source folder of your project. You will place your program files in this folder. Now that the project is set up, we will write a simple program. Add a file named hello.kt to the source folder (right-click the src folder, select New | Kotlin File/Class, and name the file hello). Copy and paste the following code into the file: fun main(args: Array<String>) { println("Hello world!") } To run the program, click the Kotlin logo adjacent to the main function and select Run HelloKt: The project will be built and run, after which, Hello world! will be printed to the standard system output. Advantages of Kotlin As previously discussed, Kotlin was designed to be a better Java, and as such, there are a number of advantages to using Kotlin over Java: Null safety: One common occurrence in Java programs is the throwing of NullPointerException. Kotlin alleviates this issue by providing a null-safe type system. Presence of extension functions: Functions can easily be added to classes defined in program files to extend their functionality in various ways. This can be done with extension functions in Kotlin. Singletons: It is easy to implement the singleton pattern in Kotlin programs. The implementation of a singleton in Java takes considerably more effort than when it is done with Kotlin. Data classes: When writing programs, it is a common scenario to have to create a class for the sole purpose of holding data in variables. This often leads to the writing of many lines of code for such a mundane task. Data classes in Kotlin make it extremely easy to create such classes that hold data with a single line of code. Function types: Unlike Java, Kotlin has function types. This enables functions to accept other functions as parameters and the definition of functions that return functions. To summarize, we introduced Kotlin and explored the fundamentals. In the process, we learned how to install, write and run Kotlin scripts on a computer and how to use the REPL and IDE. This tutorial is an excerpt from the book, Kotlin Programming By Example, written by Iyanu Adelekan. This book will help you enhance your Kotlin programming skills by building real-world applications. Build your first Android app with Kotlin How to convert Java code into Kotlin  
Read more
  • 0
  • 0
  • 12056

article-image-build-first-android-app-kotlin
Aarthi Kumaraswamy
13 Apr 2018
10 min read
Save for later

Build your first Android app with Kotlin

Aarthi Kumaraswamy
13 Apr 2018
10 min read
Android application with Kotlin is an area which shines. Before getting started on this journey, we must set up our systems for the task at hand. A major necessity for developing Android applications is a suitable IDE - it is not a requirement but it makes the development process easier. Many IDE choices exist for Android developers. The most popular are: Android Studio Eclipse IntelliJ IDE Android Studio is by far the most powerful of the IDEs available with respect to Android development. As a consequence, we will be utilizing this IDE in all Android-related chapters in this book. Setting up Android Studio At the time of writing, the version of Android Studio that comes bundled with full Kotlin support is Android Studio 3.0. The canary version of this software can be downloaded from this website. Once downloaded, open the downloaded package or executable and follow the installation instructions. A setup wizard exists to guide you through the IDE setup procedure: Continuing to the next setup screen will prompt you to choose which type of Android Studio setup you'd like: Select the Standard setup and continue to the next screen. Click Finish on the Verify Settings screen. Android Studio will now download the components required for your setup. You will need to wait a few minutes for the required components to download: Click Finish once the component download has completed. You will be taken to the Android Studio landing screen. You are now ready to use Android Studio: [box type="note" align="" class="" width=""]You may also want to read Benefits of using Kotlin Java for Android programming.[/box] Building your first Android application with Kotlin Without further ado, let's explore how to create a simple Android application with Android Studio. We will be building the HelloApp. The HelloApp is an app that displays Hello world! on the screen upon the click of a button. On the Android Studio landing screen, click Start a new Android Studio project. You will be taken to a screen where you will specify some details that concern the app you are about to build, such as the name of the application, your company domain, and the location of the project. Type in HelloApp as the application name and enter a company domain. If you do not have a company domain name, fill in any valid domain name in the company domain input box – as this is a trivial project, a legitimate domain name is not required. Specify the location in which you want to save this project and tick the checkbox for the inclusion of Kotlin support. After filling in the required parameters, continue to the next screen: Here, we are required to specify our target devices. We are building this application to run on smartphones specifically, hence tick the Phone and Tablet checkbox if it's not already ticked. You will notice an options menu next to each device option. This dropdown is used to specify the target API level for the project being created. An API level is an integer that uniquely identifies the framework API division offered by a version of the Android platform. Select API level 15 if not already selected and continue to the next screen: On the next screen, we are required to select an activity to add to our application. An activity is a single screen with a unique user interface—similar to a window. We will discuss activities in more depth in Chapter 2, Building an Android Application – Tetris. For now, select the empty activity and continue to the next screen. Now, we need to configure the activity that we just specified should be created. Name the activity HelloActivityand ensure the Generate Layout File and Backwards Compatibility checkboxes are ticked: Now, click the Finish button. Android Studio may take a few minutes to set up your project. Once the setup is complete, you will be greeted by the IDE window containing your project files. [box type="note" align="" class="" width=""]Errors pertaining to the absence of required project components may be encountered at any point during project development. Missing components can be downloaded from the SDK manager. [/box] Make sure that the project window of the IDE is open (on the navigation bar, select View | Tool Windows | Project) and the Android view is currently selected from the drop-down list at the top of the Project window. You will see the following files at the left-hand side of the window: app | java | com.mydomain.helloapp | HelloActivity.java: This is the main activity of your application. An instance of this activity is launched by the system when you build and run your application: app | res | layout | activity_hello.xml: The user interface for HelloActivity is defined within this XML file. It contains a TextView element placed within the ViewGroup of a ConstraintLayout. The text of the TextView has been set to Hello World! app | manifests | AndroidManifest.xml: The AndroidManifest file is used to describe the fundamental characteristics of your application. In addition, this is the file in which your application's components are defined. Gradle Scripts | build.gradle: Two build.gradle files will be present in your project. The first build.gradle file is for the project and the second is for the app module. You will most frequently work with the module's build.gradle file for the configuration of the compilation procedure of Gradle tools and the building of your app. [box type="note" align="" class="" width=""]Gradle is an open source build automation system used for the declaration of project configurations. In Android, Gradle is utilized as a build tool with the goal of building packages and managing application dependencies. [/box] Creating a user interface A user interface (UI) is the primary means by which a user interacts with an application. The user interfaces of Android applications are made by the creation and manipulation of layout files. Layout files are XML files that exist in app | res | layout. To create the layout for the HelloApp, we are going to do three things: Add a LinearLayout to our layout file Place the TextView within the LinearLayout and remove the android:text attribute it possesses Add a button to the LinearLayout Open the activity_hello.xml file if it's not already opened. You will be presented with the layout editor. If the editor is in the Design view, change it to its Text view by toggling the option at the bottom of the layout editor. Now, your layout editor should look similar to that of the following screenshot: ViewGroup that arranges child views in either a horizontal or vertical manner within a single column. Copy the code snippet of our required LinearLayout from the following block and paste it within the ConstraintLayout preceding the TextView: <LinearLayout android:id="@+id/ll_component_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> </LinearLayout> Now, copy and paste the TextView present in the activity_hello.xml file into the body of the LinearLayout element and remove the android:text attribute: <LinearLayout android:id="@+id/ll_component_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/tv_greeting" android:layout_width="wrap_content" android:layout_height="wrap_content"       android:textSize="50sp" /> </LinearLayout> Lastly, we need to add a button element to our layout file. This element will be a child of our LinearLayout. To create a button, we use the Button element: <LinearLayout android:id="@+id/ll_component_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/tv_greeting" android:layout_width="wrap_content" android:layout_height="wrap_content"       android:textSize="50sp" /> <Button       android:id="@+id/btn_click_me" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Click me!"/> </LinearLayout> Toggle to the layout editor's design view to see how the changes we have made thus far translate when rendered on the user interface: Now we have our layout, but there's a problem. Our CLICK ME! button does not actually do anything when clicked. We are going to fix that by adding a listener for click events to the button. Locate and open the HelloActivity.java file and edit the function to add the logic for the CLICK ME! button's click event as well as the required package imports, as shown in the following code: package com.mydomain.helloapp import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.text.TextUtils import android.widget.Button import android.widget.TextView import android.widget.Toast class HelloActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_hello) val tvGreeting = findViewById<TextView>(R.id.tv_greeting) val btnClickMe = findViewById<Button>(R.id.btn_click_me) btnClickMe.setOnClickListener { if (TextUtils.isEmpty(tvGreeting.text)) { tvGreeting.text = "Hello World!" } else { Toast.makeText(this, "I have been clicked!",                       Toast.LENGTH_LONG).show() } } } } In the preceding code snippet, we have added references to the TextView and Button elements present in our activity_hello layout file by utilizing the findViewById function. The findViewById function can be used to get references to layout elements that are within the currently-set content view. The second line of the onCreate function has set the content view of HelloActivity to the activity_hello.xml layout. Next to the findViewById function identifier, we have the TextView type written between two angular brackets. This is called a function generic. It is being used to enforce that the resource ID being passed to the findViewById belongs to a TextView element. After adding our reference objects, we set an onClickListener to btnClickMe. Listeners are used to listen for the occurrence of events within an application. In order to perform an action upon the click of an element, we pass a lambda containing the action to be performed to the element's setOnClickListener method. When btnClickMe is clicked, tvGreeting is checked to see whether it has been set to contain any text. If no text has been set to the TextView, then its text is set to Hello World!, otherwise a toast is displayed with the I have been clicked! text. Running the Android application In order to run the application, click the Run 'app' (^R) button at the top-right side of the IDE window and select a deployment target. The HelloApp will be built, installed, and launched on the deployment target: You may use one of the available prepackaged virtual devices or create a custom virtual device to use as the deployment target.  You may also decide to connect a physical Android device to your computer via USB and select it as your target. The choice is up to you. After selecting a deployment device, click OK to build and run the application. Upon launching the application, our created layout is rendered: When CLICK ME! is clicked, Hello World! is shown to the user: Subsequent clicks of the CLICK ME! button display a toast message with the text I have been clicked!: You enjoyed an excerpt from the book, Kotlin Programming By Example by Iyanu Adelekan. Start building and deploying Android apps with Kotlin using this book. Check out other related posts: Creating a custom layout implementation for your Android app Top 5 Must-have Android Applications OpenCV and Android: Making Your Apps See      
Read more
  • 0
  • 0
  • 7536
article-image-creating-a-custom-layout-implementation-for-your-android-app
Aarthi Kumaraswamy
06 Apr 2018
5 min read
Save for later

Creating a custom layout implementation for your Android app

Aarthi Kumaraswamy
06 Apr 2018
5 min read
In most applications, you'll find that a combination of the ConstraintLayout, CoordinatorLayout, and some of the more primitive layout classes (such as LinearLayout and FrameLayout) are more than enough to achieve any layout requirements you can dream up for your user interface. Every now and again though, you'll find yourself needing a custom layout manager to achieve an effect required for the application. Layout classes extend from the ViewGroup class, and their job is to tell their child widgets where to position themselves, and how large they should be. They do this in two phases: the measurement phase and the layout phase. All View implementations are expected to provide measurements for their actual size according to specifications. These measurements are then used by the View widget's parent ViewGroup to allocate the amount of space the widget will consume on the screen. For example, a View might be told to consume, at most, the screen width. The View must then determine how much of that space it actually requires, and records that size in its measured dimensions. The measured dimensions are then used by the parent ViewGroup during the layout process. The second phase is the layout phase, and it is conducted by the ViewGroup parent of each View widget. This phase positions the View on the screen, relative to its parent ViewGroup location, and specifies the actual size that the widget will consume on the screen (typically based on the measured size calculated in the measurement phase). When you implement your own ViewGroup, you'll need to ensure that all of your child View widgets are given a chance to measure themselves before you perform the actual layout operations. Let's build a layout class to arrange its children in a circle. To keep the implementation simple, we'll assume that all the child widgets are the same size (for example, if they were all icons): Right-click on the widget package in the travel claim example app, and select New|Java Class. Name the new class CircleLayout. Change the Superclass to android.view.ViewGroup. Click OK to create the new class. Declare the standard ViewGroup constructors: public CircleLayout(final Context context) {  super(context); } public CircleLayout(    final Context context,    final AttributeSet attrs) {  super(context, attrs); } public CircleLayout(      final Context context,      final AttributeSet attrs,      final int defStyleAttr) {  super(context, attrs, defStyleAttr); } Override the onMeasure method to calculate the size of the CircleLayout and all of its child Viewwidgets. The measurement specifications are passed in as int values, which are interpreted using the staticmethods in the MeaureSpec class. Measurement specifications come in two flavors: at most and exactly, and each has a size value attached. In this particular layout, we always measure the CircleLayout as the size given in the specification. This means that the CircleLayout will always consume the maximum amount of space available. It also expects all of its children to be able to specify sizes without the match_parent attribute (as this will cause each child to take up all the available space): @Override protected void onMeasure(    final int widthMeasureSpec,    final int heightMeasureSpec) {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  measureChildren(widthMeasureSpec, heightMeasureSpec);  setMeasuredDimension(        MeasureSpec.getSize(widthMeasureSpec),        MeasureSpec.getSize(heightMeasureSpec)); } The next method to implement is the onLayout method. This performs the actual arrangement of the child View widget within the CircleLayout, by invoking their layout method. The layout method should never be overridden, because it's closely tied to the platform and performs several other important actions (such as notifying layout listeners). Instead, you should override onLayout, but invoking layout.CircleLayoutassumes that all the child View widgets are of the same size (and forces this as part of the onLayoutimplementation). This onLayout method simply calculates the available space, and then positions the child View widgets in a circle around the outside edge: protected void onLayout( final boolean changed, final int left, final int top, final int right, final int bottom) { final int childCount = getChildCount(); if (childCount == 0) { return; } final int width = right - left; final int height = bottom - top; // if we have children, we assume they're all the same size final int childrenWidth = getChildAt(0).getMeasuredWidth(); final int childrenHeight = getChildAt(0).getMeasuredHeight(); final int boxSize = Math.min( width - childrenWidth, height - childrenHeight); for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); final int childWidth = child.getMeasuredWidth(); final int childHeight = child.getMeasuredHeight(); final double x = Math.sin((Math.PI * 2.0) * ((double) i / (double) childCount)); final double y = -Math.cos((Math.PI * 2.0) * ((double) i / (double) childCount)); final int childLeft = (int) (x * (boxSize / 2)) + (width / 2) - (childWidth / 2); final int childTop = (int) (y * (boxSize / 2)) + (height / 2) - (childHeight / 2); final int childRight = childLeft + childWidth; final int childBottom = childTop + childHeight; child.layout(childLeft, childTop, childRight, childBottom); } } Although the implementation of the onLayout method is quite long, it's also relatively simple. Most of the code is concerned with determining the desired position of the child View widgets. Layout code needs to execute as quickly as possible, and should avoid allocating any objects during the onMeasure and onLayout methods (similar to the rules of onDraw). Layout is a critical part of building the screen from a performance standpoint, because no rendering can actually occur without the layout being completed. The layout will also be rerun every time the layout changes its structure. For example, if you add or remove any child View widgets, or change the size or position of the ViewGroup. Changing the size of a ViewGroup might happen on every frame if you use a CoordinatorLayout, where the ViewGroup is being collapsed (or if you change its size as part of a property-animation). You read an excerpt from the book, Hands-On Android UI Development by Jason Morris. For more recipes on cutting edge Android UI tasks such as creating themes, animations, custom widgets and more, give this book a try.  
Read more
  • 0
  • 0
  • 3941

article-image-play-functions
Packt
21 Feb 2018
6 min read
Save for later

Play With Functions

Packt
21 Feb 2018
6 min read
This article by Igor Wojda and Marcin Moskala, authors of the book Android Development with Kotlin, introduces functions in Kotlin, together with different ways of calling functions. (For more resources related to this topic, see here.) Single-expression functions During typical programming, many functions contain only one expression. Here is example of this kind of function: fun square(x: Int): Int { return x * x } Or another one, which can be often found in Android projects. It is pattern used in Activity, to define methods that are just getting text from some view or providing some other data from view to allow presenter to get them: fun getEmail(): String { return emailView.text.toString() } Both functions are defined to return result of single expression. In first example it is result of x * x multiplication, and in second one it is result of expression emailView.text.toString(). This kind of functions are used all around Android projects. Here are some common use-cases: Extracting some small operations Using polymorphism to provide values specific to class Functions that are only creating some object Functions that are passing data between architecture layers (like in preceding example Activity is passing data from view to presenter) Functional programming style functions that base on recurrence Such functions are often used, so Kotlin has notation for this kind of them. When a function returns a single expression, then curly braces and body of the function can be omitted. We specify expression directly using equality character. Functions defined this way are called single-expression functions. Let's update our square function, and define it as a single-expression function: As we can see, single expression function have expression body instead of block body. This notation is shorter, but whole body needs to be just a single expression. In single-expression functions, declaring return type is optional, because it can be inferred by the compiler from type of expression. This is why we can simplify use square function, and define it this way: fun square(x: Int) = x * x There are many places inside Android application where we can utilize single expression functions. Let's consider RecyclerView adapter that is providing layout ID and creating ViewHolder: class AddressAdapter : ItemAdapter<AddressAdapter.ViewHolder>() { override fun getLayoutId() = R.layout.choose_address_view override fun onCreateViewHolder(itemView: View) = ViewHolder(itemView) // Rest of methods } In the following example, we achieve high readability thanks to single expression function. Single-expression functions are also very popular in the functional world. Single expression function notation is also well-pairing with when structure. Here example of their connection, used to get specific data from object according to key (use-case from big Kotlin project): fun valueFromBooking(key: String, booking: Booking?) = when(key) { // 1 "patient.nin" -> booking?.patient?.nin "patient.email" -> booking?.patient?.email "patient.phone" -> booking?.patient?.phone "comment" -> booking?.comment else -> null } We don't need a type, because it is inferred from when expression. Another common Android example is that we can combine when expression with activity method onOptionsItemSelected that handles top bar menu clicks: override fun onOptionsItemSelected(item: MenuItem): Boolean = when { item.itemId == android.R.id.home -> { onBackPressed() true } else -> super.onOptionsItemSelected(item) } As we can see, single expression functions can make our code more concise and improved readability. Single-expression functions are commonly used in Kotlin Android projects and they are really popular for functional programming. As an example. Let's suppose that we need to filter all the odd values from following list: val list = listOf(1, 2, 3, 4, 5) We will use following helper function that returns true if argument is odd otherwise it returns false: fun isOdd(i: Int) = i % 2 == 1 In imperative programming style, we should specify steps of processing, which are connected to execution process (iterate through list, check if value is odd, add value to one list if it's odd). Here is implementation of this functionality, that is typical for imperative style: var oddList = emptyList<Int>() for(i in list) { if(isOdd(i)) { newList += i } } In declarative programming style, the way of thinking about code is different - we should think what is the required result and simply use functions that will give us this result. Kotlin stdlib provides lot of functions supporting declarative programming style. Here is how we could implement the same functionality using one of them, called filter: var oddList = list.filter(::isOdd) filter is function that leaves only elements that are true according to predicate. Here function isOdd is used as an predicate. Different ways of calling a function Sometimes we need to call function and provide only selected arguments. In Java we could create multiple overloads of the same method, but this solution have there are some limitations. First problem is that number of possible method permutations is growing very quickly (2n) making them very difficult to maintain. Second problem is that overloads must be distinguishable from each other, so compiler will know which overload to call, so when method defines few parameters with the same type we can't define all possible overloads. That's why in Java we often need to pass multiple null values to a method: // Java printValue("abc", null, null, "!"); Multiple null parameters provide boilerplate and greatly decrease method readability. In Kotlin there is no such problem, because Kotlin has feature called default arguments and named argument syntax. Default arguments values Default arguments are mostly known from C++, which is one of the oldest languages supporting it. Default argument provides a value for a parameter in case it is not provided during method call. Each function parameter can have default value. It might be any value that is matching specified type including null. This way we can simply define functions that can be called in multiple ways We can use this function the same way as normal function (function without default argument values) by providing values for each parameter (all arguments): printValue("str", true, "","") // Prints: (str) Thanks to default argument values, we can call a function by providing arguments only for parameters without default values: printValue("str") // Prints: (str) We can also provide all parameters without default values, and only some that have a default value: printValue("str", false) // Prints: str Named arguments syntax Sometimes we want only to pass value for last argument. Let's suppose that we define want to define value for suffix, but not for prefix and inBracket (which are defined before suffix). Normally we would have to provide values for all previous parameters including the default parameter values: printValue("str", true, true, "!") // Prints: (str) By using named argument syntax, we can pass specific argument using argument name: printValue("str", suffix = "!") // Prints: (str)! We can also use named argument syntax together with classic call. The only restriction is when we start using named syntax we cannot use classic one for next arguments we are serving: printValue("str", true, "") printValue("str", true, prefix = "") printValue("str", inBracket = true, prefix = "") Summary In this article, we learned about single expression functions as a type of defining functions in application development. We also briefly explained Resources for Article:   Further resources on this subject: Getting started with Android Development [article] Android Game Development with Unity3D [article] Kotlin Basics [article]
Read more
  • 0
  • 0
  • 1868

article-image-how-convert-java-code-into-kotlin
Aanand Shekhar
14 Feb 2018
2 min read
Save for later

How to convert Java code into Kotlin

Aanand Shekhar
14 Feb 2018
2 min read
This Kotlin programming tutorial has been taken from Kotlin Programming Cookbook.  One of the best things about Kotlin is its interoperability with Java. If you're a Java programmer, that should be a reason to start learning alone. If you're using an IntelliJ-based IDE, it's actually incredibly easy to convert Java code to Kotlin. In this step-by-step recipe, you'll find out how to do it. What you need to convert your Java code to Kotlin All you need to follow this recipe is an IntelliJ-based IDE installed, which compiles and runs Kotlin and Java. How to do it... Here are the steps you need to follow to convert a Java file to a Kotlin file: In your IntelliJ IDE, open the Java file that you want to convert to Kotlin. Note that it has a .java extension. Now, in the main menu, click on Code menu and choose the Convert Java File to Kotlin File option. Your Java file will be converted into Kotlin, and the extension will now be .kt.  Here is an example of a Java file: After converting to Kotlin, this is what we have: A Kotlin file can be converted into Java, but it's better if you can avoid it or find an alternative way to do it. If you have to absolutely convert your Kotlin code to Java, click on Tools | Kotlin | Show Kotlin Bytecode in the menu: After clicking on Show Kotlin Bytecode, a window will open with the title Kotlin Bytecode: Click on Decompile and a .java file will be generated, containing a decompiled Java bytecode from Kotlin code: Yes, it has a lot of unnecessary code that was not present in the original Java code, but that is the case with decompiled bytecode. At the moment, this is the only way to convert Kotlin code to Java. Copy the decompiled file into a .java file and remove the unnecessary code. How it works Kotlin is a statically-typed programming language that works on Java Virtual Machine and compiles into JVM compatible bytecode. This is the reason we can convert Java code to Kotlin and mix Java and Kotlin code together.  This is also the reason why you can, in a way, get Java code back from Kotlin (although the output is not completely desired).
Read more
  • 0
  • 0
  • 4821
article-image-null-30
Packt
09 Feb 2018
13 min read
Save for later

Lets build applications for wear 2.0

Packt
09 Feb 2018
13 min read
In this article Ashok Kumar S, the author of the article Android Wear Projects will get you started on writing android wear applications. You probably already know that by the title of the article that we will be building wear applications, But you can also expect a little bit of story on every project and comprehensive explanation on the components and structure of the application. We will be covering most of the wear 2.0 standards and development practices in all the projects we are building. Why building wear applications? The culture of wearing a utility that helps to do certain actions have always been part of a modern civilization. Wrist watches for human beings have become an augmented helping tool for checking time and date. Wearing a watch lets you check time with just a glance. Technology has taken this wearing watch experience to next level, The first modern wearable watch was a combination of calculator and watch introduced to the world in 1970. Over the decades of advancement in microprocessors and wireless technology lead to introduce a concept called "ubiquitous computing". During this time most of the leading electronic industry, start-ups have started to work on their ideas which made wearable devices very popular. Going forward we will be building five projects enlisted below. Note taking application Fitness application Wear Maps app