Quantcast
Channel: Envato Tuts+ Code - Mobile Development
Viewing all 1836 articles
Browse latest View live

Create Chatbots on Android with IBM Watson

$
0
0

If you've ever spoken to voice-based personal assistants such as Siri or Google Now, or chatted with one of the many text-based bots active on messaging platforms such as Facebook Messenger and Kik, you probably realize how fun, intuitive, and powerful conversational user interfaces can be. However, because most natural languages are extremely complex, creating such interfaces from scratch tends be hard. Fortunately, there's IBM Watson.

By using the IBM Watson Conversation service, you can create AI-powered conversational user interfaces in minutes, often with just a few lines of code. In this tutorial, I'll introduce you to the service and show you how to use it in Android apps.

Prerequisites

To make the most of this tutorial, you'll need the following:

1. Creating a Conversation Service

Before you can use the the IBM Watson Conversation API, you must create a Conversation service on the IBM Bluemix platform and acquire login credentials for it. To do so, sign in to the Bluemix console, navigate to Services > Watson, and press the Create Watson service button. In the next screen, choose Conversation from the catalog of available services.

Watson services catalog

In the configuration form that's displayed next, type in an appropriate name for the service and press the Create button.

Conversation service configuration form

2. Creating a Conversation Workspace

A Conversation service can work only if it has at least one Conversation workspace associated with it. For now, you can think of a workspace as a collection of rules and configuration details, which defines the capabilities and personality of your conversational UI.

The Bluemix console has an easy to use tool that allows you to create and manage workspaces. To launch it,  press the Launch tool button.

Conversation workspace tool launcher

In the next screen, press the Create button to create a new workspace. In the dialog that pops up, give a meaningful name to the workspace and choose a language for it.

Workspace configuration dialog

Once the workspace has been created, you are expected to add intents, entities, and dialog details to it.

Intents entities and dialog tabs

While intents defines actions a user can perform using your conversational UI, entities define objects that are relevant to those actions. For example, in the sentence "book me a ticket from New York to Chicago", "book a ticket" would be an intent, and "New York" and "Chicago" would be entities. Dialog details define the actual responses the conversational UI generates, and how its conversations flow.

Step 1: Create Intents

In this tutorial, we'll be creating a very simple Android chatbot capable of performing the following actions:

  • greet the user
  • introduce itself
  • quote inspirational quotes

Accordingly, our chatbot needs three intents.

Press the Create New button to create the first intent. In the form that shows up, name the intent #Greeting, provide a few sample words or sentences the user might use for the intent, such as "hi" and "hello", and press the Done button.

Greeting intent creation

The best thing about the Watson Conversation service is that it intelligently trains itself using the sample user inputs you provide to the intent. Consequently, it will be able to respond to several variations of those sample inputs. For example, it will be able to correctly match words and phrases such as "howdy", "good morning", and "yo!" to the #Greeting intent.

Press the Create New button again to create the next intent. Name it #Name, and provide the following user examples.

Name intent creation

Similarly, name the third intent #RequestQuote, and provide the following user examples.

RequestQuote intent creation

Step 2: Create a Dialog

Our chatbot is so simple that we don't need to define any entities for it. Therefore, we can now directly start specifying how it responds to each intent we created.

Start by going to the Dialog tab and pressing the Create button. In the next screen, you'll see that two dialog nodes are created for you automatically: one named Welcome, which is to greet the user, and one named Anything else, which is to catch inputs the bot doesn't understand.

Default dialog nodes

For now, let's leave the Anything else node as it is, and configure the Welcome node. In the dialog that pops up, type in #Greeting in the If bot recognizes field, and then add a few responses. Obviously, the more responses you add, the more human-like your chatbot will be.

Dialog for Greeting

Next, create a new node for the #Name intent by pressing the Add Node button. Again, fill the form shown appropriately.

Dialog for Name

The node for the #RequestQuote intent is going to be slightly different. We won't be manually typing in a few inspirational quotes as the responses of this node because doing so would make our bot too static and uninteresting. Instead, our Android chatbot should be able to fetch quotes from an external API. Therefore, the responses of this node should be sentences that ask the user to wait while the bot searches for a new quote.

Dialog for RequestQuote

At this point, our workspace is ready. You can test it right away by clicking the speech balloon icon. Feel free to test it with a variety sentences to make sure that it associates the right intents with them.

Testing the workspace

Step 3: Determine Credentials

To be able to use the Conversation service in an Android app, you'll need its username and password. Additionally, you'll need the ID of the Conversation workspace. Therefore, go to the Deploy section and switch to the Credentials tab.

You should now be able to see the credentials you need. After noting them all down, you can close the Bluemix console.

Credentials tab

3. Android Studio Project Setup

Although it is possible to interact with the Conversation service using any Android networking library, using the Watson Java SDK is a better idea because it offers a very intuitive and high-level API. To add it to your Android Studio project, add the following compile dependency in the app module's build.gradle file:

Additionally, we'll be needing the Fuel networking library to fetch inspirational quotes from a remote server, and the Design support library to able to work with a few Material Design widgets.

Both Fuel and the Watson Java SDK require your app to have the INTERNET permission, so don't forget to ask for it in your project's manifest file:

Lastly, open the res/values/strings.xml file and add the Conversation service's username and password, and the Conversation workspace's ID to it as <string> tags:

You can now press the Sync Now button to complete the project setup.

4. Defining a Layout

We will be creating a text-based bot in this tutorial. Therefore, our app's layout should contain an EditText widget where users can type in their messages, and a TextView widget where the user-bot conversation can be shown. Optionally, you can place the EditText widget inside a TextInputLayout container to make sure that it follows the Material Design guidelines.

It's also a good idea to place the TextView widget inside a ScrollView container to make sure that long conversations aren't truncated.

Note that we've set the value of the EditText widget's imeOptions attribute to actionDone. This allows users to press a Done button on their virtual keyboards when they've finished typing their messages.

5. Using the Conversation Service

The ConversationService class of the Watson SDK has all the method's you'll need to communicate with the Conversation service. Therefore, the first thing you need to do in your Activity class is create an instance of it. It's constructor expects a version date, the service's username, and its password.

Next, to be able to work with the widgets present in the layout XML file, you must get references to them using the findViewById() method.

When the users have finished typing their input messages, they will be pressing the Done button on their virtual keyboards. To be able to listen to that button-press event, you must add an OnEditorActionListener to the EditText widget.

Inside the listener, you can call the getText() method of the EditText widget to fetch the user's message.

The TextView widget will be displaying both the messages of the user and the replies of the bot. Therefore, append the message to the TextView widget using its append() method.

The user's message must be sent to the Conversation service wrapped in a MessageRequest object. You can create one easily using the MessageRequest.Builder class.

Once the request is ready, you must pass it to the message() method of the ConversationService object, along with the workspace's ID. Finally, to actually send the message to the Conversation service, you must call the enqueue() method.

Because the enqueue() method runs asynchronously, you will also need a ServiceCallback object to get the service's response.

Inside the onResponse() method, you can call the getText() method of the MessageResponse object to get the Conversation service's response.

You can now append the response to the TextView widget again using its append() method. However, make sure you do so inside the runOnUiThread() method because you are currently on a different thread.

Our bot is almost ready. If you try running the app, you'll be able to get correct responses from it for the #Greeting and #Name intents. It still can't recite inspirational quotes though. Therefore, we must now add code to explicitly look for the #RequestQuote intent and generate a response manually.

To extract the name of the detected intent from the MessageResponse object, you must call its getIntents() method, which returns a list of MessageResponse.Intent objects, pick the first item, and call its getIntent() method.

There are many websites with free APIs you can use to fetch inspirational quotes. Forismatic is one of them. Its REST API provides quotes as plain text, which you can directly use in your app.

To make an HTTP request to the Forismatic API's URL, all you need to do is call the get() method of the Fuel class. Because the method runs asynchronously, you must handle the HTTP response by calling the responseString() method and passing a Handler object to it.

Inside the success() method of the handler, you can simply append the quote to the TextView widget. The following code shows you how:

The bot is now complete, and will be able to generate the right responses for all the intents we added to the workspace.

The Android chatbot running

Conclusion

Conversational user interfaces are all the rage today. They are so easy to use that everybody loves them. In this tutorial, you learned the basics of creating such interfaces on the Android platform using the IBM Watson Conversation service.

There's a lot more the service can do. To learn more about it, you can refer to the official documentation.

And be sure to check out some of our other posts on using machine learning for your Android apps!

2017-08-17T12:09:11.000Z2017-08-17T12:09:11.000ZAshraff Hathibelagal

Create Chatbots on Android with IBM Watson

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/cms-29387

If you've ever spoken to voice-based personal assistants such as Siri or Google Now, or chatted with one of the many text-based bots active on messaging platforms such as Facebook Messenger and Kik, you probably realize how fun, intuitive, and powerful conversational user interfaces can be. However, because most natural languages are extremely complex, creating such interfaces from scratch tends be hard. Fortunately, there's IBM Watson.

By using the IBM Watson Conversation service, you can create AI-powered conversational user interfaces in minutes, often with just a few lines of code. In this tutorial, I'll introduce you to the service and show you how to use it in Android apps.

Prerequisites

To make the most of this tutorial, you'll need the following:

1. Creating a Conversation Service

Before you can use the the IBM Watson Conversation API, you must create a Conversation service on the IBM Bluemix platform and acquire login credentials for it. To do so, sign in to the Bluemix console, navigate to Services > Watson, and press the Create Watson service button. In the next screen, choose Conversation from the catalog of available services.

Watson services catalog

In the configuration form that's displayed next, type in an appropriate name for the service and press the Create button.

Conversation service configuration form

2. Creating a Conversation Workspace

A Conversation service can work only if it has at least one Conversation workspace associated with it. For now, you can think of a workspace as a collection of rules and configuration details, which defines the capabilities and personality of your conversational UI.

The Bluemix console has an easy to use tool that allows you to create and manage workspaces. To launch it,  press the Launch tool button.

Conversation workspace tool launcher

In the next screen, press the Create button to create a new workspace. In the dialog that pops up, give a meaningful name to the workspace and choose a language for it.

Workspace configuration dialog

Once the workspace has been created, you are expected to add intents, entities, and dialog details to it.

Intents entities and dialog tabs

While intents defines actions a user can perform using your conversational UI, entities define objects that are relevant to those actions. For example, in the sentence "book me a ticket from New York to Chicago", "book a ticket" would be an intent, and "New York" and "Chicago" would be entities. Dialog details define the actual responses the conversational UI generates, and how its conversations flow.

Step 1: Create Intents

In this tutorial, we'll be creating a very simple Android chatbot capable of performing the following actions:

  • greet the user
  • introduce itself
  • quote inspirational quotes

Accordingly, our chatbot needs three intents.

Press the Create New button to create the first intent. In the form that shows up, name the intent #Greeting, provide a few sample words or sentences the user might use for the intent, such as "hi" and "hello", and press the Done button.

Greeting intent creation

The best thing about the Watson Conversation service is that it intelligently trains itself using the sample user inputs you provide to the intent. Consequently, it will be able to respond to several variations of those sample inputs. For example, it will be able to correctly match words and phrases such as "howdy", "good morning", and "yo!" to the #Greeting intent.

Press the Create New button again to create the next intent. Name it #Name, and provide the following user examples.

Name intent creation

Similarly, name the third intent #RequestQuote, and provide the following user examples.

RequestQuote intent creation

Step 2: Create a Dialog

Our chatbot is so simple that we don't need to define any entities for it. Therefore, we can now directly start specifying how it responds to each intent we created.

Start by going to the Dialog tab and pressing the Create button. In the next screen, you'll see that two dialog nodes are created for you automatically: one named Welcome, which is to greet the user, and one named Anything else, which is to catch inputs the bot doesn't understand.

Default dialog nodes

For now, let's leave the Anything else node as it is, and configure the Welcome node. In the dialog that pops up, type in #Greeting in the If bot recognizes field, and then add a few responses. Obviously, the more responses you add, the more human-like your chatbot will be.

Dialog for Greeting

Next, create a new node for the #Name intent by pressing the Add Node button. Again, fill the form shown appropriately.

Dialog for Name

The node for the #RequestQuote intent is going to be slightly different. We won't be manually typing in a few inspirational quotes as the responses of this node because doing so would make our bot too static and uninteresting. Instead, our Android chatbot should be able to fetch quotes from an external API. Therefore, the responses of this node should be sentences that ask the user to wait while the bot searches for a new quote.

Dialog for RequestQuote

At this point, our workspace is ready. You can test it right away by clicking the speech balloon icon. Feel free to test it with a variety sentences to make sure that it associates the right intents with them.

Testing the workspace

Step 3: Determine Credentials

To be able to use the Conversation service in an Android app, you'll need its username and password. Additionally, you'll need the ID of the Conversation workspace. Therefore, go to the Deploy section and switch to the Credentials tab.

You should now be able to see the credentials you need. After noting them all down, you can close the Bluemix console.

Credentials tab

3. Android Studio Project Setup

Although it is possible to interact with the Conversation service using any Android networking library, using the Watson Java SDK is a better idea because it offers a very intuitive and high-level API. To add it to your Android Studio project, add the following compile dependency in the app module's build.gradle file:

Additionally, we'll be needing the Fuel networking library to fetch inspirational quotes from a remote server, and the Design support library to able to work with a few Material Design widgets.

Both Fuel and the Watson Java SDK require your app to have the INTERNET permission, so don't forget to ask for it in your project's manifest file:

Lastly, open the res/values/strings.xml file and add the Conversation service's username and password, and the Conversation workspace's ID to it as <string> tags:

You can now press the Sync Now button to complete the project setup.

4. Defining a Layout

We will be creating a text-based bot in this tutorial. Therefore, our app's layout should contain an EditText widget where users can type in their messages, and a TextView widget where the user-bot conversation can be shown. Optionally, you can place the EditText widget inside a TextInputLayout container to make sure that it follows the Material Design guidelines.

It's also a good idea to place the TextView widget inside a ScrollView container to make sure that long conversations aren't truncated.

Note that we've set the value of the EditText widget's imeOptions attribute to actionDone. This allows users to press a Done button on their virtual keyboards when they've finished typing their messages.

5. Using the Conversation Service

The ConversationService class of the Watson SDK has all the method's you'll need to communicate with the Conversation service. Therefore, the first thing you need to do in your Activity class is create an instance of it. It's constructor expects a version date, the service's username, and its password.

Next, to be able to work with the widgets present in the layout XML file, you must get references to them using the findViewById() method.

When the users have finished typing their input messages, they will be pressing the Done button on their virtual keyboards. To be able to listen to that button-press event, you must add an OnEditorActionListener to the EditText widget.

Inside the listener, you can call the getText() method of the EditText widget to fetch the user's message.

The TextView widget will be displaying both the messages of the user and the replies of the bot. Therefore, append the message to the TextView widget using its append() method.

The user's message must be sent to the Conversation service wrapped in a MessageRequest object. You can create one easily using the MessageRequest.Builder class.

Once the request is ready, you must pass it to the message() method of the ConversationService object, along with the workspace's ID. Finally, to actually send the message to the Conversation service, you must call the enqueue() method.

Because the enqueue() method runs asynchronously, you will also need a ServiceCallback object to get the service's response.

Inside the onResponse() method, you can call the getText() method of the MessageResponse object to get the Conversation service's response.

You can now append the response to the TextView widget again using its append() method. However, make sure you do so inside the runOnUiThread() method because you are currently on a different thread.

Our bot is almost ready. If you try running the app, you'll be able to get correct responses from it for the #Greeting and #Name intents. It still can't recite inspirational quotes though. Therefore, we must now add code to explicitly look for the #RequestQuote intent and generate a response manually.

To extract the name of the detected intent from the MessageResponse object, you must call its getIntents() method, which returns a list of MessageResponse.Intent objects, pick the first item, and call its getIntent() method.

There are many websites with free APIs you can use to fetch inspirational quotes. Forismatic is one of them. Its REST API provides quotes as plain text, which you can directly use in your app.

To make an HTTP request to the Forismatic API's URL, all you need to do is call the get() method of the Fuel class. Because the method runs asynchronously, you must handle the HTTP response by calling the responseString() method and passing a Handler object to it.

Inside the success() method of the handler, you can simply append the quote to the TextView widget. The following code shows you how:

The bot is now complete, and will be able to generate the right responses for all the intents we added to the workspace.

The Android chatbot running

Conclusion

Conversational user interfaces are all the rage today. They are so easy to use that everybody loves them. In this tutorial, you learned the basics of creating such interfaces on the Android platform using the IBM Watson Conversation service.

There's a lot more the service can do. To learn more about it, you can refer to the official documentation.

And be sure to check out some of our other posts on using machine learning for your Android apps!

2017-08-17T12:09:11.000Z2017-08-17T12:09:11.000ZAshraff Hathibelagal

3 Terrible Mistakes of iOS Developers

$
0
0

Coding an iOS app is hard work, so it makes sense that devs want to cut corners and find ways to get their app online as quickly as possible. But a successful app will be around for a long time—that means years of bug fixing, feature enhancements, and working with other coders. 

In this article, I'll share three things to steer clear of during iOS development that will make your apps easier to build and easier to maintain.

1. Don't Be Afraid of Constants

While it seems that variables are more versatile than constants, it still isn't a good idea to default to variables when you can use a constant instead. So what's so great about constants? A number of things, actually!

Readability

One of the best things about constants is their readability. Let's look at an example: you are writing an e-commerce type app. You may want to add a local sales tax rate of 8.75%, but other developers wouldn't know what that number means. Let's look at an example: 

A developer named Steven comes aboard your team, and he is a coding ninja, but he lives in a country overseas. In this country, there is no such thing as sales tax (lucky Steven), and therefore, he doesn't know anything about it. 

If you were to use a variable for your sales tax rate, he could change it in just one line of code, and the results of that could seriously harm your app. Just changing the keyword from var to let would have the compiler telling him that the value cannot be changed, and he would realize that you intended it to be immutable.

Value Reference

Another way that let is useful is to refer to a value in your code. If you are making an app, you may want a certain color scheme. Instead of copy-pasting your colors wherever they are needed, you can use a constant to refer to that specific color.

This way, if you were to change the color, you would just need to change it in one place instead of finding every single reference to the color and changing it multiple times.

Class or Struct Instantiation 

When you create a singleton, you also need to create a shared instance of the class. You would usually do this by declaring a static let inside of the class declaration. After that, you would name the constant and assign it to an instance of the class and use it throughout your app.

Adding to that, if you needed to instantiate (create an instance of) a regular class, perhaps in ViewController.swift, you would create a constant and assign it to an instance of your desired class, leaving you with a reference that you can easily take advantage of throughout the file. This is another great use of constants.

As you can see, there are many reasons that constants are great. They increase code readability, they are useful for storing immutable values, and clearly, they are not as useless as you think. Do yourself a favor by getting in the habit of using constants whenever possible, and only changing them into variables if you absolutely need to mutate their values—it will make you a better programmer.

2. Don't Force Unwrap Optionals

Optionals are a very powerful feature of Swift. They are just types like int and String, annotated by a question mark after the type declaration. If you want to declare a variable as an optional string, you would just write:

This tells the compiler that there either can be a value or there might be no value at all. String? and String are considered to be two different types.

Think of optionals as a gift box. As I mentioned, this gift box may or may not have a value, and if you want to find out, you must unwrap the optional first. There are many ways of doing this:

The Wrong Way

Forced Unwrapping

This operation (performed by using an exclamation mark) is called the Bang Operator. Don't use it! Force unwrapping your variables is never a good idea. If the value of the optional you are trying to unwrap is nil (nothing), your app will crash, and who wants that? Anyway, let's look at the following block of code:

In this example, the app would crash because we never defined a value for someVariable, and we are trying to assign it to a variable of type String. This defeats the whole purpose of optionals, which are there to help protect us from errors like this! 

Let's look at some of the correct ways of handling this same situation.

The Right Way

Optional Binding 

This is one of the most popular methods of dealing with optionals. In this method, you simply assign an optional value to a constant using an if statement. If the optional can be unwrapped, the compiler enters the closure, and you can use the constant that was created. Otherwise, you fall into an else statement and pretend that nothing happened. Let's look at an example of this:

Using the same example as last time, but with optional binding instead, we can see that instead of crashing, the compiler enters the else statement and prints "error."

Optional Chaining

Another common way to safely unwrap optionals is optional chaining. This is a great way to avoid nil values cleanly, and in one line of code. When you use this method and come across a nil value, that line of code simply ceases to execute. Here's an example of this:

Basically, if someClass is nil, the entire line will not execute, and the value of somethingElse will become nil. If there is a value, like the example above, it will be assigned to the variable somethingElse. In either case, the app will not crash.

Nil Coalescing

This method handles optionals with a single line, but unlike the method above, you need to provide a default or "else" case (in case the optional turns out to be nil). Let's look at an example:

Although this may seem a little cryptic, it simply means that if the left-hand statement has a value (in other words is not nil), it will be used. If it is nil, then the default statement will be used—in this case, a hard-coded string. It is worth noting that the right-hand statement needs to be of a non-nil and non-optional type (otherwise, the purpose of this would be defeated).

3. Don't Ignore Architecture

Another common mistake is failing to structure your code in a way that it is sustainable, maintainable, and efficient. Many people cram all of their code into their ViewController classes, and this can make your code hard to change and debug.

As cliché as this may sound, this really is the foundation of how you program your app. Let's say you are building a house, your dream home. This house is five stories high, so if you don't build a strong foundation and follow the blueprints, it will probably just topple over.

The foundation of an iOS app is the design pattern that you choose. Let's look at two of the most commonly used patterns.

MVC (Model-View-Controller)

The Model-View-Controller or MVC design pattern separates each part of your code into three parts: the model, the view, and the controller. 

  • Model: The model is essentially the data of the app. This handles things like reusable structures and classes that deal only with the data of the app. The model does not handle anything relating to the view or how the information will be shown to the user.
  • View: The view is responsible for only the visual representation of the data, and it also handles user interaction. It does not handle anything regarding data, nor does it deal with specific views. It is simply a reusable class which can be used multiple times without repeating code.
  • Controller: The controller is the boss. It brings data from the model, and then sends it to the view to finally display it to the user. This is typically in ViewController.swift, and it listens to input and changes the model as needed.

There are many variations of this, such as MVVM and MVP. It's worth reading up on them, but the principle is similar to MVC, so we won't be covering them here. These are all called design patterns, and they make our code modular. 

Let's look at another design pattern which can complement the app pattern you choose to use.

Singletons

A singleton is a single instance of a class that is present at all times in memory. So why do we care about this? Well, let's say that you are building an app that connects to a database. You need a place to put all of your data service connections. This would be a perfect place to use singletons. Look at the code below; it will show you how to construct a singleton:

If you follow these simple tips, your app will be easier to maintain, and bugs will be more obvious to find before your customers do.

Conclusion

In this article, we saw three mistakes that iOS app developers make that might seem to make coding easier, but actually cost a lot more work in the long term. 

Remember, building an app is only part of the challenge—you also need to fix bugs, add features, and share the code with other developers. Following best practices like using constants, handling optionals correctly, and using architectural patterns will make your app easier to build and easier to maintain.

While you're here, check out some of our other posts on iOS app development!

2017-08-21T12:55:53.000Z2017-08-21T12:55:53.000ZVardhan Agrawal

Create Chatbots on Android With IBM Watson

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/cms-29387

If you've ever spoken to voice-based personal assistants such as Siri or Google Now, or chatted with one of the many text-based bots active on messaging platforms such as Facebook Messenger and Kik, you probably realize how fun, intuitive, and powerful conversational user interfaces can be. However, because most natural languages are extremely complex, creating such interfaces from scratch tends to be hard. Fortunately, there's IBM Watson.

By using the IBM Watson Conversation service, you can create AI-powered conversational user interfaces in minutes, often with just a few lines of code. In this tutorial, I'll introduce you to the service and show you how to use it in Android apps.

Prerequisites

To make the most of this tutorial, you'll need the following:

1. Creating a Conversation Service

Before you can use the IBM Watson Conversation API, you must create a Conversation service on the IBM Bluemix platform and acquire login credentials for it. To do so, sign in to the Bluemix console, navigate to Services > Watson, and press the Create Watson service button. On the next screen, choose Conversation from the catalog of available services.

Watson services catalog

In the configuration form that's displayed next, type in an appropriate name for the service and press the Create button.

Conversation service configuration form

2. Creating a Conversation Workspace

A Conversation service can work only if it has at least one Conversation workspace associated with it. For now, you can think of a workspace as a collection of rules and configuration details, which defines the capabilities and personality of your conversational UI.

The Bluemix console has an easy-to-use tool that allows you to create and manage workspaces. To launch it, press the Launch tool button.

Conversation workspace tool launcher

In the next screen, press the Create button to create a new workspace. In the dialog that pops up, give a meaningful name to the workspace and choose a language for it.

Workspace configuration dialog

Once the workspace has been created, you are expected to add intents, entities, and dialog details to it.

Intents entities and dialog tabs

While intents define actions a user can perform using your conversational UI, entities define objects that are relevant to those actions. For example, in the sentence "book me a ticket from New York to Chicago", "book a ticket" would be an intent, and "New York" and "Chicago" would be entities. Dialog details define the actual responses the conversational UI generates, and how its conversations flow.

Step 1: Create Intents

In this tutorial, we'll be creating a very simple Android chatbot capable of performing the following actions:

  • greet the user
  • introduce itself
  • quote inspirational quotes

Accordingly, our chatbot needs three intents.

Press the Create New button to create the first intent. In the form that shows up, name the intent #Greeting, provide a few sample words or sentences the user might use for the intent, such as "hi" and "hello", and press the Done button.

Greeting intent creation

The best thing about the Watson Conversation service is that it intelligently trains itself using the sample user inputs you provide to the intent. Consequently, it will be able to respond to several variations of those sample inputs. For example, it will be able to correctly match words and phrases such as "howdy", "good morning", and "yo!" to the #Greeting intent.

Press the Create New button again to create the next intent. Name it #Name, and provide the following user examples.

Name intent creation

Similarly, name the third intent #RequestQuote, and provide the following user examples.

RequestQuote intent creation

Step 2: Create a Dialog

Our chatbot is so simple that we don't need to define any entities for it. Therefore, we can now directly start specifying how it responds to each intent we created.

Start by going to the Dialog tab and pressing the Create button. In the next screen, you'll see that two dialog nodes are created for you automatically: one named Welcome, which is to greet the user, and one named Anything else, which is to catch inputs the bot doesn't understand.

Default dialog nodes

For now, let's leave the Anything else node as it is, and configure the Welcome node. In the dialog that pops up, type in #Greeting in the If bot recognizes field, and then add a few responses. Obviously, the more responses you add, the more human-like your chatbot will be.

Dialog for Greeting

Next, create a new node for the #Name intent by pressing the Add Node button. Again, fill the form shown appropriately.

Dialog for Name

The node for the #RequestQuote intent is going to be slightly different. We won't be manually typing in a few inspirational quotes as the responses of this node because doing so would make our bot too static and uninteresting. Instead, our Android chatbot should be able to fetch quotes from an external API. Therefore, the responses of this node should be sentences that ask the user to wait while the bot searches for a new quote.

Dialog for RequestQuote

At this point, our workspace is ready. You can test it right away by clicking the speech balloon icon. Feel free to test it with a variety of sentences to make sure that it associates the right intents with them.

Testing the workspace

Step 3: Determine Credentials

To be able to use the Conversation service in an Android app, you'll need its username and password. Additionally, you'll need the ID of the Conversation workspace. Therefore, go to the Deploy section and switch to the Credentials tab.

You should now be able to see the credentials you need. After noting them all down, you can close the Bluemix console.

Credentials tab

3. Android Studio Project Setup

Although it is possible to interact with the Conversation service using any Android networking library, using the Watson Java SDK is a better idea because it offers a very intuitive and high-level API. To add it to your Android Studio project, add the following compile dependency in the app module's build.gradle file:

Additionally, we'll be needing the Fuel networking library to fetch inspirational quotes from a remote server, and the Design support library to able to work with a few Material Design widgets.

Both Fuel and the Watson Java SDK require your app to have the INTERNET permission, so don't forget to ask for it in your project's manifest file:

Lastly, open the res/values/strings.xml file and add the Conversation service's username and password, and the Conversation workspace's ID to it as <string> tags:

You can now press the Sync Now button to complete the project setup.

4. Defining a Layout

We will be creating a text-based bot in this tutorial. Therefore, our app's layout should contain an EditText widget where users can type in their messages, and a TextView widget where the user-bot conversation can be shown. Optionally, you can place the EditText widget inside a TextInputLayout container to make sure that it follows the Material Design guidelines.

It's also a good idea to place the TextView widget inside a ScrollView container to make sure that long conversations aren't truncated.

Note that we've set the value of the EditText widget's imeOptions attribute to actionDone. This allows users to press a Done button on their virtual keyboards when they've finished typing their messages.

5. Using the Conversation Service

The ConversationService class of the Watson SDK has all the methods you'll need to communicate with the Conversation service. Therefore, the first thing you need to do in your Activity class is create an instance of it. Its constructor expects a version date, the service's username, and its password.

Next, to be able to work with the widgets present in the layout XML file, you must get references to them using the findViewById() method.

When the users have finished typing their input messages, they will be pressing the Done button on their virtual keyboards. To be able to listen to that button-press event, you must add an OnEditorActionListener to the EditText widget.

Inside the listener, you can call the getText() method of the EditText widget to fetch the user's message.

The TextView widget will be displaying both the messages of the user and the replies of the bot. Therefore, append the message to the TextView widget using its append() method.

The user's message must be sent to the Conversation service wrapped in a MessageRequest object. You can create one easily using the MessageRequest.Builder class.

Once the request is ready, you must pass it to the message() method of the ConversationService object, along with the workspace's ID. Finally, to actually send the message to the Conversation service, you must call the enqueue() method.

Because the enqueue() method runs asynchronously, you will also need a ServiceCallback object to get the service's response.

Inside the onResponse() method, you can call the getText() method of the MessageResponse object to get the Conversation service's response.

You can now append the response to the TextView widget again using its append() method. However, make sure you do so inside the runOnUiThread() method because you are currently on a different thread.

Our bot is almost ready. If you try running the app, you'll be able to get correct responses from it for the #Greeting and #Name intents. It still can't recite inspirational quotes, though. Therefore, we must now add code to explicitly look for the #RequestQuote intent and generate a response manually.

To extract the name of the detected intent from the MessageResponse object, you must call its getIntents() method, which returns a list of MessageResponse.Intent objects, pick the first item, and call its getIntent() method.

There are many websites with free APIs you can use to fetch inspirational quotes. Forismatic is one of them. Its REST API provides quotes as plain text, which you can directly use in your app.

To make an HTTP request to the Forismatic API's URL, all you need to do is call the get() method of the Fuel class. Because the method runs asynchronously, you must handle the HTTP response by calling the responseString() method and passing a Handler object to it.

Inside the success() method of the handler, you can simply append the quote to the TextView widget. The following code shows you how:

The bot is now complete, and will be able to generate the right responses for all the intents we added to the workspace.

The Android chatbot running

Conclusion

Conversational user interfaces are all the rage today. They are so easy to use that everybody loves them. In this tutorial, you learned the basics of creating such interfaces on the Android platform using the IBM Watson Conversation service.

There's a lot more the service can do. To learn more about it, you can refer to the official documentation.

And be sure to check out some of our other posts on using machine learning for your Android apps!

2017-08-17T12:09:11.000Z2017-08-17T12:09:11.000ZAshraff Hathibelagal

3 Terrible Mistakes of iOS Developers

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/cms-29355

Coding an iOS app is hard work, so it makes sense that devs want to cut corners and find ways to get their app online as quickly as possible. But a successful app will be around for a long time—that means years of bug fixing, feature enhancements, and working with other coders. 

In this article, I'll share three things to steer clear of during iOS development that will make your apps easier to build and easier to maintain.

1. Don't Be Afraid of Constants

While it seems that variables are more versatile than constants, it still isn't a good idea to default to variables when you can use a constant instead. So what's so great about constants? A number of things, actually!

Readability

One of the best things about constants is their readability. Let's look at an example: you are writing an e-commerce type app. You may want to add a local sales tax rate of 8.75%, but other developers wouldn't know what that number means. Let's look at an example: 

A developer named Steven comes aboard your team, and he is a coding ninja, but he lives in a country overseas. In this country, there is no such thing as sales tax (lucky Steven), and therefore, he doesn't know anything about it. 

If you were to use a variable for your sales tax rate, he could change it in just one line of code, and the results of that could seriously harm your app. Just changing the keyword from var to let would have the compiler telling him that the value cannot be changed, and he would realize that you intended it to be immutable.

Value Reference

Another way that let is useful is to refer to a value in your code. If you are making an app, you may want a certain color scheme. Instead of copy-pasting your colors wherever they are needed, you can use a constant to refer to that specific color.

This way, if you were to change the color, you would just need to change it in one place instead of finding every single reference to the color and changing it multiple times.

Class or Struct Instantiation 

When you create a singleton, you also need to create a shared instance of the class. You would usually do this by declaring a static let inside of the class declaration. After that, you would name the constant and assign it to an instance of the class and use it throughout your app.

Adding to that, if you needed to instantiate (create an instance of) a regular class, perhaps in ViewController.swift, you would create a constant and assign it to an instance of your desired class, leaving you with a reference that you can easily take advantage of throughout the file. This is another great use of constants.

As you can see, there are many reasons that constants are great. They increase code readability, they are useful for storing immutable values, and clearly, they are not as useless as you think. Do yourself a favor by getting in the habit of using constants whenever possible, and only changing them into variables if you absolutely need to mutate their values—it will make you a better programmer.

2. Don't Force Unwrap Optionals

Optionals are a very powerful feature of Swift. They are just types like int and String, annotated by a question mark after the type declaration. If you want to declare a variable as an optional string, you would just write:

This tells the compiler that there either can be a value or there might be no value at all. String? and String are considered to be two different types.

Think of optionals as a gift box. As I mentioned, this gift box may or may not have a value, and if you want to find out, you must unwrap the optional first. There are many ways of doing this:

The Wrong Way

Forced Unwrapping

This operation (performed by using an exclamation mark) is called the Bang Operator. Don't use it! Force unwrapping your variables is never a good idea. If the value of the optional you are trying to unwrap is nil (nothing), your app will crash, and who wants that? Anyway, let's look at the following block of code:

In this example, the app would crash because we never defined a value for someVariable, and we are trying to assign it to a variable of type String. This defeats the whole purpose of optionals, which are there to help protect us from errors like this! 

Let's look at some of the correct ways of handling this same situation.

The Right Way

Optional Binding 

This is one of the most popular methods of dealing with optionals. In this method, you simply assign an optional value to a constant using an if statement. If the optional can be unwrapped, the compiler enters the closure, and you can use the constant that was created. Otherwise, you fall into an else statement and pretend that nothing happened. Let's look at an example of this:

Using the same example as last time, but with optional binding instead, we can see that instead of crashing, the compiler enters the else statement and prints "error."

Optional Chaining

Another common way to safely unwrap optionals is optional chaining. This is a great way to avoid nil values cleanly, and in one line of code. When you use this method and come across a nil value, that line of code simply ceases to execute. Here's an example of this:

Basically, if someClass is nil, the entire line will not execute, and the value of somethingElse will become nil. If there is a value, like the example above, it will be assigned to the variable somethingElse. In either case, the app will not crash.

Nil Coalescing

This method handles optionals with a single line, but unlike the method above, you need to provide a default or "else" case (in case the optional turns out to be nil). Let's look at an example:

Although this may seem a little cryptic, it simply means that if the left-hand statement has a value (in other words is not nil), it will be used. If it is nil, then the default statement will be used—in this case, a hard-coded string. It is worth noting that the right-hand statement needs to be of a non-nil and non-optional type (otherwise, the purpose of this would be defeated).

3. Don't Ignore Architecture

Another common mistake is failing to structure your code in a way that it is sustainable, maintainable, and efficient. Many people cram all of their code into their ViewController classes, and this can make your code hard to change and debug.

As cliché as this may sound, this really is the foundation of how you program your app. Let's say you are building a house, your dream home. This house is five stories high, so if you don't build a strong foundation and follow the blueprints, it will probably just topple over.

The foundation of an iOS app is the design pattern that you choose. Let's look at two of the most commonly used patterns.

MVC (Model-View-Controller)

The Model-View-Controller or MVC design pattern separates each part of your code into three parts: the model, the view, and the controller. 

  • Model: The model is essentially the data of the app. This handles things like reusable structures and classes that deal only with the data of the app. The model does not handle anything relating to the view or how the information will be shown to the user.
  • View: The view is responsible for only the visual representation of the data, and it also handles user interaction. It does not handle anything regarding data, nor does it deal with specific views. It is simply a reusable class which can be used multiple times without repeating code.
  • Controller: The controller is the boss. It brings data from the model, and then sends it to the view to finally display it to the user. This is typically in ViewController.swift, and it listens to input and changes the model as needed.

There are many variations of this, such as MVVM and MVP. It's worth reading up on them, but the principle is similar to MVC, so we won't be covering them here. These are all called design patterns, and they make our code modular. 

Let's look at another design pattern which can complement the app pattern you choose to use.

Singletons

A singleton is a single instance of a class that is present at all times in memory. So why do we care about this? Well, let's say that you are building an app that connects to a database. You need a place to put all of your data service connections. This would be a perfect place to use singletons. Look at the code below; it will show you how to construct a singleton:

If you follow these simple tips, your app will be easier to maintain, and bugs will be more obvious to find before your customers do.

Conclusion

In this article, we saw three mistakes that iOS app developers make that might seem to make coding easier, but actually cost a lot more work in the long term. 

Remember, building an app is only part of the challenge—you also need to fix bugs, add features, and share the code with other developers. Following best practices like using constants, handling optionals correctly, and using architectural patterns will make your app easier to build and easier to maintain.

While you're here, check out some of our other posts on iOS app development!

2017-08-21T12:55:53.000Z2017-08-21T12:55:53.000ZVardhan Agrawal

Kotlin From Scratch: Ranges and Collections

$
0
0

Kotlin is a modern programming language that compiles to Java bytecode. It is free and open source, and promises to make coding for Android even more fun.

In the previous article in this series, you learned about nullability, loops, and conditions in Kotlin. In this tutorial, we'll continue to learn the language by looking at the ranges and collections API in Kotlin.

1. Ranges

A Range in Kotlin is a unique type that defines a start value and an end value. In other words, it is an interval between a start and an end value. Ranges in Kotlin are closed, meaning that the start value and end value are included in the range. 

We'll now look at the different ways of creating ranges in Kotlin.

The .. Operator

In the code above, we have created a closed range. This variable oneToFive will include the following values: 1, 2, 3, 4, 5. We can loop over it using the for loop construct.

The code above can be shortened to:

We can also create a range of characters:

The variable aToZ will have all the letters in the English alphabet.

The rangeTo() Function

The .. operator can be replaced with the rangeTo() extension function to create a range. For example, we can also do this 1.rangeTo(5) and it would still have the same results as using the .. operator as discussed earlier. 

The downTo() Function

This is another extension function that will create a range starting from a given number down to another one.

We can modify the range using the step() function. This will modify the delta between each element in the range.

The code above will contain odd numbers between 1 and 10.

The in Operator

The in operator is used to ascertain whether a value is present in a given range.

In the code above, we checked to see if 5 is in the range 1..10 using the in operator. We can also do the opposite by using !n to check if 5 is not in the range.

2. Collections

Collections are used to store groups of related objects in memory. In a collection, we can retrieve, store or organize the objects. Kotlin provides its collections API as a standard library built on top of the Java Collections API. (We'll discuss interfaces in Kotlin in a future post.) 

You should note that these interfaces are linked to their implementation at compile time. You can't see the implementation source code in Kotlin, because the collections are actually implemented by the standard Java Collections such as ArrayListMapsHashMapSetsHashSetList and so on. To really understand the collections API in Kotlin, you'll need to be familiar with these basic classes and interfaces in Java.

In this section, we'll learn about the List, Set and Map collections in Kotlin. (If you want a refresher on arrays in Kotlin, kindly visit the first tutorial in this series.) 

Kotlin's collections give us the ability to achieve a lot with just a little code—unlike in Java, which seems to need a lot of code to achieve a little! Kotlin has two variants of collections: mutable and immutable. A mutable collection provides us with the ability to modify a collection by either adding, removing or replacing an element. Immutable collections cannot be modified and don't have these helper methods. 

Note that the addition, removal or replacement of an element in an immutable collection is possible via operator functions (we'll get to that shortly), but these will end up creating a new collection.

The Iterable Interface

The Kotlin Iterable interface is at the top of the collections class hierarchy. This interface enables collections to be represented as a sequence of elements (which can be iterated over, naturally). 

The Collection Interface

The Kotlin Collection interface extends the Iterable interface. The Collection interface is immutable. In other words, you have read-only access to collections. The Set and List interfaces (more about these shortly) in Kotlin extend this interface. 

Some of the functions and properties available in the Collection interface are:

  • size: this property returns the size of the collection.
  • isEmpty(): returns true if the collection is empty or false otherwise. 
  • contains(element: E): returns true if the element specified in the argument is present in the collection.
  • containsAll(element: Collection<E>): returns true if the element in the collection passed as argument is present in the collection.  

The MutableIterable Interface

This interface in Kotlin gives us a specialized mutable iterator from the parent Iterable interface.

The MutableCollection Interface

The MutableCollection interface in Kotlin is a specialized interface that enables collections to be mutable. In other words, add and remove operations can be performed on a given collection. This interface extends both the Collection interface and the MutableIterable interface already discussed above. The MutableSet and MutableList interfaces (we'll get to them shortly) in Kotlin extend this interface. The functions available in this interface—apart from the ones available in its parents—are:

  • add(element: E): adds the element passed as an argument to the collection and returns true if successful or false if the collection does not support duplicates and the element is already present.
  • remove(element: E): removes the element passed as an argument from the collection. Returns true if successful or false if it was not present in the collection.
  • addAll(elements: Collection<E>): adds all the elements in the collection passed as arguments to the collection. Returns true if successful or false if nothing was added.
  • removeAll(elements: Collection<E>): removes all of the elements present in the collection passed as arguments. Returns true if successful or false if nothing was removed.
  • retainAll(elements: Collection<E>): retains only the elements present in the collections passed as arguments. Returns true if successful or false if nothing was retained. 
  • clear(): removes all elements from this collection.

Now you have learned about the top interfaces in the collection class hierarchy in Kotlin, let's now look into how Kotlin handles collections such as Lists, Sets and Maps in the remaining part of the tutorial.

Lists

A list is an ordered collection of elements. This is a popular collection that is widely used. Let's look at different ways of creating a list in Kotlin.

Using the listOf() Function

In Kotlin, we can create an immutable (read-only) list using the listOf() helper function from the Kotlin standard library. This function returns a Kotlin List interface type.

Running the code above will print: 

Moreover, we can pass values of different types into the listOf() as arguments and the result will still work—it will be a list of mixed type. 

Using the emptyList() Function

This function just creates an empty immutable list and returns a Kotlin List interface type.

Using the listOfNotNull() Function

This function creates a new immutable list containing only elements that are not null. Notice that this function returns a Kotlin List interface type also.

The List interface from the Kotlin standard library extends only the Collection interface. In other words, its only parent is the Collection interface. It overrides all the functions in the parent interface to cater for its special needs and also defines its own functions, such as:

  • get(index: Int): a function operator that returns the element at the specified index. 
  • indexOf(element: E): returns the index of the first occurrence of the element passed as an argument in the list, or -1 if none is found.
  • lastIndexOf(element: E): returns the index of the last occurrence of the element passed as an argument in the list, or -1 if none is found. 
  • listIterator(): returns a list iterator over the elements in the list.
  • subList(fromIndex: Int, toIndex: Int): returns a list that contains the portion of the list between the specified start and end indices. 

Using the arrayListOf() Function

This creates a mutable list and returns a Java ArrayList type.

Using the mutableListOf() Function

To add, remove or replace values in a list, we need to make the list a mutable one. We can convert an immutable list to a mutable one by calling the function toMutableList() on the list. However, note that this method will create a new list.

To create a mutable list of a certain type from scratch, e.g. String, we use mutableListOf<String>(), while for mixed types we can just use the mutableListOf() function instead.

Any of these functions will return a MutableList Kotlin interface type. This interface extends both the MutableCollection and List interfaces discussed earlier in this section. The MutableList interface adds methods for the retrieval or substitution of an item based upon its position: 

  • set(index: Int, element: E): substitutes an element in the list with another element. This returns the element previously at the specified position.
  • add(index: Int, element: E): inserts an element at the specified index. 
  • removeAt(index: Int): gets rid of the element at a particular index. 

Running the code above, we produce the following result:

Note that all these functions create a Java ArrayList behind the scenes.

Sets

A set is an unordered collection of unique elements. In other words, it can't have any duplicates! Let's look at some of the different ways of creating a set in Kotlin. Each of these creates a different data structure, each of which is optimized for a certain kind of task. 

Using the setOf() Function

To create an immutable (read-only) set in Kotlin, we can use the function setOf(), which returns a Kotlin Set interface type. 

Note that the Kotlin Set interface extends only the Kotlin Collection interface and overrides all the properties available in its parent.

Using the hashSetOf() Function 

Using the hashSetOf() function creates a Java HashSet collection which stores elements in a hash table. Because this function returns a Java HashSet type, we can add, remove, or clear elements in the set. In other words, it's mutable. 

Using the sortedSetOf() Function

Using the sortedSetOf() function creates a Java TreeSet collection behind the scenes, which orders elements based on their natural ordering or by a comparator. This set is also mutable.

Using the linkedSetOf() Function

This function returns a Java LinkedHashSet type. This mutable set maintains a linked list of the entries in the set, in the order in which they were inserted. 

Using the mutableSetOf() Function

We can use mutableSetOf() to create a mutable set. This function returns a Kotlin MutableSet interface type. Behind the scenes, this function simply creates a Java LinkedHashSet.  

The MutableSet interface extends both the MutableCollection and the Set interfaces. 

Maps

Maps associate keys to values. The keys must be unique, but the associated values don't need to be. That way, each key can be used to uniquely identify the associated value, since the map makes sure that you can't have duplicate keys in the collection. Behind the scenes, Kotlin uses the Java Map collection to implement its map collection type.

Using the mapOf() Function

To create an immutable or read-only Map collection in Kotlin, we use the mapOf() function. We create a map with this function by giving it a list of pairs—the first value is the key, and the second is the value. Calling this function returns a Kotlin Map interface type.

Running the code above will produce the result: 

Unlike the List and Set interfaces in Kotlin that extend the Collection interface, the Map interface doesn't extend any at all. Some of the properties and functions available in this interface are:

  • size: this property returns the size of map collection.
  • isEmpty(): returns true if the map is empty or false otherwise.
  • containsKey(key: K): returns true if the map contains the key in the argument. 
  • containsValue(value: V): returns true if the map maps one or more keys to the value passed as an argument.
  • get(key: K): returns the value matching the given key or 'null' if none is found. 
  • keys: this property returns an immutable Set of all the keys in the map.
  • values: returns an immutable Collection of all the values in the map.

Using the mutableMapOf() Function

The mutableMapOf() function creates a mutable map for us so that we can add and remove elements in the map. This returns a Kotlin MutableMap interface type.

The MutableMap interface doesn't extend the MutableCollection interface; it's only parent is the Map interface. It overrides the keysentries and values properties from the parent interface in order to redefine them. Here are some of the extra functions available in the MutableMap interface:

  • put(key: K, value: V): inserts the key, value pair into the map. This will return the previous value linked with the key or null if the key was not previously used. 
  • remove(key: K): removes the key and its linked value from the map. 
  • putAll(from: Map<out K, V>): updates the map with all the data from the given map. New keys will be added, and existing keys will be updated with new values. 
  • clear(): removes all elements from the map. 

We can get the value for a key using the get() function. We can also use square bracket notation as a shortcut for get()

Using the hashMapOf() Function

Using this function returns a Java HashMap type that is mutable. The HashMap class uses a hash table to implement the Java Map interface.  

Using the linkedHashMap() Function

This function returns a Java LinkedHashMap type that is mutable. The LinkedHashMap class extends Java HashMap and maintains a linked list of the entries in the map in the order in which they were inserted. 

Using the sortedMapOf() Function

This function returns a Java SortedMap type which is mutable. The Java SortedMap class sees that the entries in the map are maintained in an ascending key order.

Remember, implementation of these collection interfaces in Kotlin happens at compile time.

Collections Operation Functions

Kotlin provides us with many useful operator functions called extension functions that can be invoked on collections. Let's take a look at some of the most useful.

The last() Function

This operator function returns the last element in a collection such as a list or set. We can also supply a predicate to search within a subset of elements.

The first() Function

This operator function returns the first element when invoked on a collection such as a list or set. If a predicate is given, it then uses the predicate to restrict the operation to a subset of elements.

The max() Function

Invoking this operator function on a collection such as a list or set returns the largest element, or null if no largest element is found.

The drop() Function

Calling this operator function returns a new list or set containing all elements except the first n elements.

The plus() Function

This operator function returns a collection containing all elements of the original and then the given element if it isn't already in the collection. This will end up creating a new list instead of modifying the list.

The minus() Function

The opposite of the plus() function is the minus() function. It returns a collection containing all elements of the original set except the given element. This also ends up creating a new list instead of altering the list.

The average() Function

Calling this operator function will return an average number of elements in the collection.

Most of these extension functions are available in the Kotlin collections standard library. You are advised to check out the documentation to learn about the others.

Conclusion

In this tutorial, you learned about the range and collections API in the Kotlin programming language. In the next tutorial in the Kotlin From Scratch series, you'll be introduced to functions in Kotlin. See you soon!

To learn more about the Kotlin language, I recommend visiting the Kotlin documentation. Or check out some of our other Android app development posts here on Envato Tuts!

2017-08-25T18:00:00.000Z2017-08-25T18:00:00.000ZChike Mgbemena

Kotlin From Scratch: Ranges and Collections

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/cms-29397

Kotlin is a modern programming language that compiles to Java bytecode. It is free and open source, and promises to make coding for Android even more fun.

In the previous article in this series, you learned about nullability, loops, and conditions in Kotlin. In this tutorial, we'll continue to learn the language by looking at the ranges and collections API in Kotlin.

1. Ranges

A Range in Kotlin is a unique type that defines a start value and an end value. In other words, it is an interval between a start and an end value. Ranges in Kotlin are closed, meaning that the start value and end value are included in the range. 

We'll now look at the different ways of creating ranges in Kotlin.

The .. Operator

In the code above, we have created a closed range. This variable oneToFive will include the following values: 1, 2, 3, 4, 5. We can loop over it using the for loop construct.

The code above can be shortened to:

We can also create a range of characters:

The variable aToZ will have all the letters in the English alphabet.

The rangeTo() Function

The .. operator can be replaced with the rangeTo() extension function to create a range. For example, we can also do this 1.rangeTo(5) and it would still have the same results as using the .. operator as discussed earlier. 

The downTo() Function

This is another extension function that will create a range starting from a given number down to another one.

We can modify the range using the step() function. This will modify the delta between each element in the range.

The code above will contain odd numbers between 1 and 10.

The in Operator

The in operator is used to ascertain whether a value is present in a given range.

In the code above, we checked to see if 5 is in the range 1..10 using the in operator. We can also do the opposite by using !n to check if 5 is not in the range.

2. Collections

Collections are used to store groups of related objects in memory. In a collection, we can retrieve, store or organize the objects. Kotlin provides its collections API as a standard library built on top of the Java Collections API. (We'll discuss interfaces in Kotlin in a future post.) 

You should note that these interfaces are linked to their implementation at compile time. You can't see the implementation source code in Kotlin, because the collections are actually implemented by the standard Java Collections such as ArrayListMapsHashMapSetsHashSetList and so on. To really understand the collections API in Kotlin, you'll need to be familiar with these basic classes and interfaces in Java.

In this section, we'll learn about the List, Set and Map collections in Kotlin. (If you want a refresher on arrays in Kotlin, kindly visit the first tutorial in this series.) 

Kotlin's collections give us the ability to achieve a lot with just a little code—unlike in Java, which seems to need a lot of code to achieve a little! Kotlin has two variants of collections: mutable and immutable. A mutable collection provides us with the ability to modify a collection by either adding, removing or replacing an element. Immutable collections cannot be modified and don't have these helper methods. 

Note that the addition, removal or replacement of an element in an immutable collection is possible via operator functions (we'll get to that shortly), but these will end up creating a new collection.

The Iterable Interface

The Kotlin Iterable interface is at the top of the collections class hierarchy. This interface enables collections to be represented as a sequence of elements (which can be iterated over, naturally). 

The Collection Interface

The Kotlin Collection interface extends the Iterable interface. The Collection interface is immutable. In other words, you have read-only access to collections. The Set and List interfaces (more about these shortly) in Kotlin extend this interface. 

Some of the functions and properties available in the Collection interface are:

  • size: this property returns the size of the collection.
  • isEmpty(): returns true if the collection is empty or false otherwise. 
  • contains(element: E): returns true if the element specified in the argument is present in the collection.
  • containsAll(element: Collection<E>): returns true if the element in the collection passed as argument is present in the collection.  

The MutableIterable Interface

This interface in Kotlin gives us a specialized mutable iterator from the parent Iterable interface.

The MutableCollection Interface

The MutableCollection interface in Kotlin is a specialized interface that enables collections to be mutable. In other words, add and remove operations can be performed on a given collection. This interface extends both the Collection interface and the MutableIterable interface already discussed above. The MutableSet and MutableList interfaces (we'll get to them shortly) in Kotlin extend this interface. The functions available in this interface—apart from the ones available in its parents—are:

  • add(element: E): adds the element passed as an argument to the collection and returns true if successful or false if the collection does not support duplicates and the element is already present.
  • remove(element: E): removes the element passed as an argument from the collection. Returns true if successful or false if it was not present in the collection.
  • addAll(elements: Collection<E>): adds all the elements in the collection passed as arguments to the collection. Returns true if successful or false if nothing was added.
  • removeAll(elements: Collection<E>): removes all of the elements present in the collection passed as arguments. Returns true if successful or false if nothing was removed.
  • retainAll(elements: Collection<E>): retains only the elements present in the collections passed as arguments. Returns true if successful or false if nothing was retained. 
  • clear(): removes all elements from this collection.

Now you have learned about the top interfaces in the collection class hierarchy in Kotlin, let's now look into how Kotlin handles collections such as Lists, Sets and Maps in the remaining part of the tutorial.

Lists

A list is an ordered collection of elements. This is a popular collection that is widely used. Let's look at different ways of creating a list in Kotlin.

Using the listOf() Function

In Kotlin, we can create an immutable (read-only) list using the listOf() helper function from the Kotlin standard library. This function returns a Kotlin List interface type.

Running the code above will print: 

Moreover, we can pass values of different types into the listOf() as arguments and the result will still work—it will be a list of mixed type. 

Using the emptyList() Function

This function just creates an empty immutable list and returns a Kotlin List interface type.

Using the listOfNotNull() Function

This function creates a new immutable list containing only elements that are not null. Notice that this function returns a Kotlin List interface type also.

The List interface from the Kotlin standard library extends only the Collection interface. In other words, its only parent is the Collection interface. It overrides all the functions in the parent interface to cater for its special needs and also defines its own functions, such as:

  • get(index: Int): a function operator that returns the element at the specified index. 
  • indexOf(element: E): returns the index of the first occurrence of the element passed as an argument in the list, or -1 if none is found.
  • lastIndexOf(element: E): returns the index of the last occurrence of the element passed as an argument in the list, or -1 if none is found. 
  • listIterator(): returns a list iterator over the elements in the list.
  • subList(fromIndex: Int, toIndex: Int): returns a list that contains the portion of the list between the specified start and end indices. 

Using the arrayListOf() Function

This creates a mutable list and returns a Java ArrayList type.

Using the mutableListOf() Function

To add, remove or replace values in a list, we need to make the list a mutable one. We can convert an immutable list to a mutable one by calling the function toMutableList() on the list. However, note that this method will create a new list.

To create a mutable list of a certain type from scratch, e.g. String, we use mutableListOf<String>(), while for mixed types we can just use the mutableListOf() function instead.

Any of these functions will return a MutableList Kotlin interface type. This interface extends both the MutableCollection and List interfaces discussed earlier in this section. The MutableList interface adds methods for the retrieval or substitution of an item based upon its position: 

  • set(index: Int, element: E): substitutes an element in the list with another element. This returns the element previously at the specified position.
  • add(index: Int, element: E): inserts an element at the specified index. 
  • removeAt(index: Int): gets rid of the element at a particular index. 

Running the code above, we produce the following result:

Note that all these functions create a Java ArrayList behind the scenes.

Sets

A set is an unordered collection of unique elements. In other words, it can't have any duplicates! Let's look at some of the different ways of creating a set in Kotlin. Each of these creates a different data structure, each of which is optimized for a certain kind of task. 

Using the setOf() Function

To create an immutable (read-only) set in Kotlin, we can use the function setOf(), which returns a Kotlin Set interface type. 

Note that the Kotlin Set interface extends only the Kotlin Collection interface and overrides all the properties available in its parent.

Using the hashSetOf() Function 

Using the hashSetOf() function creates a Java HashSet collection which stores elements in a hash table. Because this function returns a Java HashSet type, we can add, remove, or clear elements in the set. In other words, it's mutable. 

Using the sortedSetOf() Function

Using the sortedSetOf() function creates a Java TreeSet collection behind the scenes, which orders elements based on their natural ordering or by a comparator. This set is also mutable.

Using the linkedSetOf() Function

This function returns a Java LinkedHashSet type. This mutable set maintains a linked list of the entries in the set, in the order in which they were inserted. 

Using the mutableSetOf() Function

We can use mutableSetOf() to create a mutable set. This function returns a Kotlin MutableSet interface type. Behind the scenes, this function simply creates a Java LinkedHashSet.  

The MutableSet interface extends both the MutableCollection and the Set interfaces. 

Maps

Maps associate keys to values. The keys must be unique, but the associated values don't need to be. That way, each key can be used to uniquely identify the associated value, since the map makes sure that you can't have duplicate keys in the collection. Behind the scenes, Kotlin uses the Java Map collection to implement its map collection type.

Using the mapOf() Function

To create an immutable or read-only Map collection in Kotlin, we use the mapOf() function. We create a map with this function by giving it a list of pairs—the first value is the key, and the second is the value. Calling this function returns a Kotlin Map interface type.

Running the code above will produce the result: 

Unlike the List and Set interfaces in Kotlin that extend the Collection interface, the Map interface doesn't extend any at all. Some of the properties and functions available in this interface are:

  • size: this property returns the size of map collection.
  • isEmpty(): returns true if the map is empty or false otherwise.
  • containsKey(key: K): returns true if the map contains the key in the argument. 
  • containsValue(value: V): returns true if the map maps one or more keys to the value passed as an argument.
  • get(key: K): returns the value matching the given key or 'null' if none is found. 
  • keys: this property returns an immutable Set of all the keys in the map.
  • values: returns an immutable Collection of all the values in the map.

Using the mutableMapOf() Function

The mutableMapOf() function creates a mutable map for us so that we can add and remove elements in the map. This returns a Kotlin MutableMap interface type.

The MutableMap interface doesn't extend the MutableCollection interface; it's only parent is the Map interface. It overrides the keysentries and values properties from the parent interface in order to redefine them. Here are some of the extra functions available in the MutableMap interface:

  • put(key: K, value: V): inserts the key, value pair into the map. This will return the previous value linked with the key or null if the key was not previously used. 
  • remove(key: K): removes the key and its linked value from the map. 
  • putAll(from: Map<out K, V>): updates the map with all the data from the given map. New keys will be added, and existing keys will be updated with new values. 
  • clear(): removes all elements from the map. 

We can get the value for a key using the get() function. We can also use square bracket notation as a shortcut for get()

Using the hashMapOf() Function

Using this function returns a Java HashMap type that is mutable. The HashMap class uses a hash table to implement the Java Map interface.  

Using the linkedHashMap() Function

This function returns a Java LinkedHashMap type that is mutable. The LinkedHashMap class extends Java HashMap and maintains a linked list of the entries in the map in the order in which they were inserted. 

Using the sortedMapOf() Function

This function returns a Java SortedMap type which is mutable. The Java SortedMap class sees that the entries in the map are maintained in an ascending key order.

Remember, implementation of these collection interfaces in Kotlin happens at compile time.

Collections Operation Functions

Kotlin provides us with many useful operator functions called extension functions that can be invoked on collections. Let's take a look at some of the most useful.

The last() Function

This operator function returns the last element in a collection such as a list or set. We can also supply a predicate to search within a subset of elements.

The first() Function

This operator function returns the first element when invoked on a collection such as a list or set. If a predicate is given, it then uses the predicate to restrict the operation to a subset of elements.

The max() Function

Invoking this operator function on a collection such as a list or set returns the largest element, or null if no largest element is found.

The drop() Function

Calling this operator function returns a new list or set containing all elements except the first n elements.

The plus() Function

This operator function returns a collection containing all elements of the original and then the given element if it isn't already in the collection. This will end up creating a new list instead of modifying the list.

The minus() Function

The opposite of the plus() function is the minus() function. It returns a collection containing all elements of the original set except the given element. This also ends up creating a new list instead of altering the list.

The average() Function

Calling this operator function will return an average number of elements in the collection.

Most of these extension functions are available in the Kotlin collections standard library. You are advised to check out the documentation to learn about the others.

Conclusion

In this tutorial, you learned about the range and collections API in the Kotlin programming language. In the next tutorial in the Kotlin From Scratch series, you'll be introduced to functions in Kotlin. See you soon!

To learn more about the Kotlin language, I recommend visiting the Kotlin documentation. Or check out some of our other Android app development posts here on Envato Tuts!

2017-08-25T18:00:00.000Z2017-08-25T18:00:00.000ZChike Mgbemena

Why MVC Might Not Be the Best Pattern for Cocoa Apps

$
0
0

MVC stands for Model-View-Controller, and it's a widespread architectural pattern for software development. It's the de facto design pattern for Cocoa development, and it has been for many, many years. Most of us can't imagine building applications without it. Both UIKit (iOS) and AppKit (macOS) make frequent use of MVC. It almost seems as if we don't have another option to build applications for iOS, tvOS, macOS, and watchOS.

Even if you're unfamiliar with the Model-View-Controller pattern, if you have the ambition to develop applications for one of Apple's platforms, you need to learn how views (iOS) and windows (macOS) relate to controllers and which role the model plays in a typical Cocoa application. Fortunately, MVC is easy to learn.

In this short series, I explain what MVC is, what it looks like in a typical Cocoa application, and why it may not be the best solution for Cocoa developers.

1. An Example

Let me show you what the MVC pattern looks like in a typical Cocoa application. The example I'll be showing you focuses on iOS, but everything we discuss also applies to tvOS, macOS, and watchOS. Open Xcode and create a new iOS project based on the Single View Application template.

Setting Up the Project

Name the project MVC, and set Language to Swift and Devices to iPhone. I'm using Xcode 8 for this tutorial. The project's configuration options may look a bit different if you're using Xcode 9.

Configuring the Project

As the name implies, the Model-View-Controller pattern defines three components, the model, the view, and the controller. Let me show you where you can find these components in a typical iOS project.

Controllers

The controllers of an iOS application are view controllers, instances of the UIViewController class or a subclass thereof. The UIViewController class is defined in the UIKit framework. Because we chose the Single View Application template when we set up the project, Xcode created a controller for us to start with, the ViewController class, defined in ViewController.Swift. It inherits from the UIViewController class.

As the name implies, a UIViewController instance is responsible for controlling a view, an instance of the UIView class. Every view controller in an iOS project keeps a strong reference to a view, another component of the Model-View-Controller pattern. The UIView class is also defined in the UIKit framework.

Views

We can find the view component in the main storyboard of the project. Open Main.storyboard in the Project Navigator on the left and inspect the View Controller Scene. The scene contains a view controller, an instance of the ViewController class, and it manages a UIView instance.

Exploring the Main Storyboard of the Project

Select View in the storyboard on the left and open the Identity Inspector on the right. The Class field of the view is set to UIView. In an iOS application, views are typically instances of UIKit's UIView class or a subclass thereof.

View Is Instance of UIView Class

Models

Thus far we've explored the controller layer and the view layer. But where can we find the model layer of the project? The model is almost always specific to the project you're working on, and it's up to you to define, implement, and use the model of the project. I write model, but you usually have multiple models, depending on the complexity of your project.

Let's add the final piece of the MVC puzzle by creating a model. Create a new Swift file and name it Person.swift.

Create a New Swift File

Select Person.swift in the Project Navigator on the left and define a structure named Person. We define three properties: 

  • firstName of type String
  • lastName of type String
  • age of type Int

You now have a model you can use in your project. Let's keep it simple and define a property, person, of type Person? in the ViewController class. We create a Person instance in the view controller's viewDidLoad() method and assign it to the person property.

What we see in this example is very common in Cocoa applications powered by the Model-View-Controller pattern. The view controller owns and manages the model, and it uses the model to populate its view. In a more complex application, you load the model's data from a persistent store or fetch it from a remote back end.

Let's define an outlet for a UILabel instance in the view controller and, in the main storyboard, add a label to the View Controller Scene.

Adding a Label to the View Controller Scene

In the view controller's viewDidLoad() method, we safely unwrap the value stored in the person property and use its data to set the text property of the UILabel instance.

The result isn't very surprising if you're familiar with Cocoa development. This is what we end up with.

MVC in Action

2. What Is Model-View-Controller?

The Model-View-Controller pattern is easy to understand and pick up. Despite its simplicity, you can find a wide range of flavors of the MVC pattern. MVC only offers a basic blueprint that can be modified to the platform it is used on. 

The Model-View-Controller pattern you're familiar with on iOS, tvOS, macOS, and watchOS differs in subtle ways from the original definition. While the differences compared with the original definition are subtle, they have a significant impact on the code you write as well as on the maintainability of the project.

Smalltalk

The Model-View-Controller pattern is an old design pattern. It made its first appearance in the 1970s in Smalltalk. The pattern was conceived by Trygve Reenskaug. Over the years, the Model-View-Controller pattern made its way into many languages and frameworks, including Java, Rails, and Django.

I mentioned earlier that the MVC pattern breaks applications up into three distinct components: model, view, and controller. The original implementation of the pattern defines that the view is responsible for displaying the model's data to the user. The user interacts with the application through the view layer. The controller is in charge of handling user interaction and manipulating the model's data as a result. The view visualizes these changes to the user. As illustrated in the below diagram, the model plays a key role in the MVC pattern as it was designed by Reenskaug.

MVC as Defined by Trygve Reenskaug

MVC and Cocoa

The implementation we use in Cocoa development differs from Reenskaug's original design. Take a look at the below diagram to better understand what these differences entail.

MVC Cocoa Implementation

As I mentioned earlier, the view and the controller share a close relationship. In a typical iOS application, a controller holds a strong reference to the view it manages. The view is a dumb object that knows how to display data and respond to user interaction. The result is a highly reusable component.

The controller plays a vital role in Cocoa applications powered by the Model-View-Controller pattern. It takes over some of the tasks of the model in Reenskaug's original MVC implementation. The view and the model don't communicate directly with one another. Instead, the model is usually owned by the controller, which it uses to configure and populate the view it manages.

I hope you can see the subtle differences between Reenskaug's original implementation in Smalltalk and the Cocoa implementation we have become accustomed to. The differences are minor, but, as I'll discuss in a moment, the impact they have is important.

3. The Good: Separation of Concerns and Reusability

Before we take a look at the problems MVC introduces, I'd like to show you why the Model-View-Controller pattern has become such a popular and widespread pattern in software development. The Model-View-Controller pattern we use in Cocoa development has a number of clear benefits it inherited from Reenskaug's original implementation.

The most obvious advantage of the Model-View-Controller pattern is a separation of concerns. The view layer, for example, is responsible for presenting data to the user. The model and controller layers are not concerned with data presentation. But if you've been using MVC in a Cocoa project, then you know that this isn't always true. I'll talk more about that in a moment.

A direct benefit of this separation of concerns is reusability. Each of the components of the Model-View-Controller pattern is focused on a specific task, which means that the building blocks of an MVC application are often easy to reuse. It also allows for these components to be loosely coupled, increasing their reusability. This isn't true for every component, though. In a Cocoa project, for example, controllers are often specific to the application and not good candidates for reuse.

The views and models of a project, however, are highly reusable if designed correctly. Table and collection views, for example, are UIView subclasses that are used in millions of applications. Because a table view delegates user interaction to another object and asks a data source for the data it needs to display, it can focus exclusively on data presentation and user interaction.

4. The Bad: Massive View Controllers

Most developers quickly grasp what the Model-View-Controller pattern brings to the table and how it should be implemented. Unfortunately, the Model-View-Controller pattern also has an ugly side. I already wrote about reusability and separation of concerns. I'm sure I don't need to convince you of these benefits. A table view is highly reusable and incredibly performant. Developers can use standard UIKit components in their applications without any need for subclassing or customization.

Hitting the Limits of MVC

But that's only part of the story. You know when you're starting to hit the limits of MVC when massive view controllers have sneaked into your project. It's time for change when you're ploughing through hundreds or thousands of lines of code to find that one method you're looking for. 

Dumping It in the Controller

Most developers know what goes into the view and model layers of a typical Cocoa application powered by the Model-View-Controller pattern. But which component is responsible for formatting the data that's displayed to the user? Remember that views are supposed to be dumb and reusable. The view shouldn't need to format data. Right? It should only know how to present data and respond to user interaction. Should the model be concerned with data formatting?

And what about networking? That's certainly not the task of the view. Should it be delegated to the model? That doesn't sound right. Why don't we slip that piece of code into the controller. It doesn't feel right, but it'll do for now.

After many lines of code, you end up with a controller that is ready to burst and a nightmare to test. Testing? I hear you. I wouldn't want to test a view controller suffering from massive view controller syndrome either.

5. A Better Solution

You started with good intentions, but you ended up with a project that has a collection of overweight controllers that are difficult to manage and maintain. You're not looking forward to adding new features to the project you're working on because opening up those view controllers makes you sick in your stomach. Does this sound familiar?

It's important to realize that this is a common scenario. Many developers hit the limits of the Model-View-Controller pattern and realize they need something better. Chances are that you've already been looking at several alternatives, such as MVP (Model-View-Presenter) or MVVM (Model-View-ViewModel).

In the next installment of this series, I'll zoom in on the Model-View-ViewModel pattern. It will feel strangely familiar if you've already worked with the Model-View-Controller pattern. But the Model-View-ViewModel pattern brings a few improvements to the table that work very well for Cocoa development.

And while you're waiting, check out some of our other posts on Cocoa app development!

2017-08-28T15:00:00.000Z2017-08-28T15:00:00.000ZBart Jacobs

Why MVC Might Not Be the Best Pattern for Cocoa Apps

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/cms-29423

MVC stands for Model-View-Controller, and it's a widespread architectural pattern for software development. It's the de facto design pattern for Cocoa development, and it has been for many, many years. Most of us can't imagine building applications without it. Both UIKit (iOS) and AppKit (macOS) make frequent use of MVC. It almost seems as if we don't have another option to build applications for iOS, tvOS, macOS, and watchOS.

Even if you're unfamiliar with the Model-View-Controller pattern, if you have the ambition to develop applications for one of Apple's platforms, you need to learn how views (iOS) and windows (macOS) relate to controllers and which role the model plays in a typical Cocoa application. Fortunately, MVC is easy to learn.

In this short series, I explain what MVC is, what it looks like in a typical Cocoa application, and why it may not be the best solution for Cocoa developers.

1. An Example

Let me show you what the MVC pattern looks like in a typical Cocoa application. The example I'll be showing you focuses on iOS, but everything we discuss also applies to tvOS, macOS, and watchOS. Open Xcode and create a new iOS project based on the Single View Application template.

Setting Up the Project

Name the project MVC, and set Language to Swift and Devices to iPhone. I'm using Xcode 8 for this tutorial. The project's configuration options may look a bit different if you're using Xcode 9.

Configuring the Project

As the name implies, the Model-View-Controller pattern defines three components, the model, the view, and the controller. Let me show you where you can find these components in a typical iOS project.

Controllers

The controllers of an iOS application are view controllers, instances of the UIViewController class or a subclass thereof. The UIViewController class is defined in the UIKit framework. Because we chose the Single View Application template when we set up the project, Xcode created a controller for us to start with, the ViewController class, defined in ViewController.Swift. It inherits from the UIViewController class.

As the name implies, a UIViewController instance is responsible for controlling a view, an instance of the UIView class. Every view controller in an iOS project keeps a strong reference to a view, another component of the Model-View-Controller pattern. The UIView class is also defined in the UIKit framework.

Views

We can find the view component in the main storyboard of the project. Open Main.storyboard in the Project Navigator on the left and inspect the View Controller Scene. The scene contains a view controller, an instance of the ViewController class, and it manages a UIView instance.

Exploring the Main Storyboard of the Project

Select View in the storyboard on the left and open the Identity Inspector on the right. The Class field of the view is set to UIView. In an iOS application, views are typically instances of UIKit's UIView class or a subclass thereof.

View Is Instance of UIView Class

Models

Thus far we've explored the controller layer and the view layer. But where can we find the model layer of the project? The model is almost always specific to the project you're working on, and it's up to you to define, implement, and use the model of the project. I write model, but you usually have multiple models, depending on the complexity of your project.

Let's add the final piece of the MVC puzzle by creating a model. Create a new Swift file and name it Person.swift.

Create a New Swift File

Select Person.swift in the Project Navigator on the left and define a structure named Person. We define three properties: 

  • firstName of type String
  • lastName of type String
  • age of type Int

You now have a model you can use in your project. Let's keep it simple and define a property, person, of type Person? in the ViewController class. We create a Person instance in the view controller's viewDidLoad() method and assign it to the person property.

What we see in this example is very common in Cocoa applications powered by the Model-View-Controller pattern. The view controller owns and manages the model, and it uses the model to populate its view. In a more complex application, you load the model's data from a persistent store or fetch it from a remote back end.

Let's define an outlet for a UILabel instance in the view controller and, in the main storyboard, add a label to the View Controller Scene.

Adding a Label to the View Controller Scene

In the view controller's viewDidLoad() method, we safely unwrap the value stored in the person property and use its data to set the text property of the UILabel instance.

The result isn't very surprising if you're familiar with Cocoa development. This is what we end up with.

MVC in Action

2. What Is Model-View-Controller?

The Model-View-Controller pattern is easy to understand and pick up. Despite its simplicity, you can find a wide range of flavors of the MVC pattern. MVC only offers a basic blueprint that can be modified to the platform it is used on. 

The Model-View-Controller pattern you're familiar with on iOS, tvOS, macOS, and watchOS differs in subtle ways from the original definition. While the differences compared with the original definition are subtle, they have a significant impact on the code you write as well as on the maintainability of the project.

Smalltalk

The Model-View-Controller pattern is an old design pattern. It made its first appearance in the 1970s in Smalltalk. The pattern was conceived by Trygve Reenskaug. Over the years, the Model-View-Controller pattern made its way into many languages and frameworks, including Java, Rails, and Django.

I mentioned earlier that the MVC pattern breaks applications up into three distinct components: model, view, and controller. The original implementation of the pattern defines that the view is responsible for displaying the model's data to the user. The user interacts with the application through the view layer. The controller is in charge of handling user interaction and manipulating the model's data as a result. The view visualizes these changes to the user. As illustrated in the below diagram, the model plays a key role in the MVC pattern as it was designed by Reenskaug.

MVC as Defined by Trygve Reenskaug

MVC and Cocoa

The implementation we use in Cocoa development differs from Reenskaug's original design. Take a look at the below diagram to better understand what these differences entail.

MVC Cocoa Implementation

As I mentioned earlier, the view and the controller share a close relationship. In a typical iOS application, a controller holds a strong reference to the view it manages. The view is a dumb object that knows how to display data and respond to user interaction. The result is a highly reusable component.

The controller plays a vital role in Cocoa applications powered by the Model-View-Controller pattern. It takes over some of the tasks of the model in Reenskaug's original MVC implementation. The view and the model don't communicate directly with one another. Instead, the model is usually owned by the controller, which it uses to configure and populate the view it manages.

I hope you can see the subtle differences between Reenskaug's original implementation in Smalltalk and the Cocoa implementation we have become accustomed to. The differences are minor, but, as I'll discuss in a moment, the impact they have is important.

3. The Good: Separation of Concerns and Reusability

Before we take a look at the problems MVC introduces, I'd like to show you why the Model-View-Controller pattern has become such a popular and widespread pattern in software development. The Model-View-Controller pattern we use in Cocoa development has a number of clear benefits it inherited from Reenskaug's original implementation.

The most obvious advantage of the Model-View-Controller pattern is a separation of concerns. The view layer, for example, is responsible for presenting data to the user. The model and controller layers are not concerned with data presentation. But if you've been using MVC in a Cocoa project, then you know that this isn't always true. I'll talk more about that in a moment.

A direct benefit of this separation of concerns is reusability. Each of the components of the Model-View-Controller pattern is focused on a specific task, which means that the building blocks of an MVC application are often easy to reuse. It also allows for these components to be loosely coupled, increasing their reusability. This isn't true for every component, though. In a Cocoa project, for example, controllers are often specific to the application and not good candidates for reuse.

The views and models of a project, however, are highly reusable if designed correctly. Table and collection views, for example, are UIView subclasses that are used in millions of applications. Because a table view delegates user interaction to another object and asks a data source for the data it needs to display, it can focus exclusively on data presentation and user interaction.

4. The Bad: Massive View Controllers

Most developers quickly grasp what the Model-View-Controller pattern brings to the table and how it should be implemented. Unfortunately, the Model-View-Controller pattern also has an ugly side. I already wrote about reusability and separation of concerns. I'm sure I don't need to convince you of these benefits. A table view is highly reusable and incredibly performant. Developers can use standard UIKit components in their applications without any need for subclassing or customization.

Hitting the Limits of MVC

But that's only part of the story. You know when you're starting to hit the limits of MVC when massive view controllers have sneaked into your project. It's time for change when you're ploughing through hundreds or thousands of lines of code to find that one method you're looking for. 

Dumping It in the Controller

Most developers know what goes into the view and model layers of a typical Cocoa application powered by the Model-View-Controller pattern. But which component is responsible for formatting the data that's displayed to the user? Remember that views are supposed to be dumb and reusable. The view shouldn't need to format data. Right? It should only know how to present data and respond to user interaction. Should the model be concerned with data formatting?

And what about networking? That's certainly not the task of the view. Should it be delegated to the model? That doesn't sound right. Why don't we slip that piece of code into the controller. It doesn't feel right, but it'll do for now.

After many lines of code, you end up with a controller that is ready to burst and a nightmare to test. Testing? I hear you. I wouldn't want to test a view controller suffering from massive view controller syndrome either.

5. A Better Solution

You started with good intentions, but you ended up with a project that has a collection of overweight controllers that are difficult to manage and maintain. You're not looking forward to adding new features to the project you're working on because opening up those view controllers makes you sick in your stomach. Does this sound familiar?

It's important to realize that this is a common scenario. Many developers hit the limits of the Model-View-Controller pattern and realize they need something better. Chances are that you've already been looking at several alternatives, such as MVP (Model-View-Presenter) or MVVM (Model-View-ViewModel).

In the next installment of this series, I'll zoom in on the Model-View-ViewModel pattern. It will feel strangely familiar if you've already worked with the Model-View-Controller pattern. But the Model-View-ViewModel pattern brings a few improvements to the table that work very well for Cocoa development.

And while you're waiting, check out some of our other posts on Cocoa app development!

2017-08-28T15:00:00.000Z2017-08-28T15:00:00.000ZBart Jacobs

17 Ways to Make your Mobile App Beautiful with Envato Elements

$
0
0

If you are a mobile app developer or interested in getting into designing apps and you haven’t heard of Envato Elements, this post is for you.

Launched just last year, Envato Elements allows you to download unlimited digital assets for a single affordable monthly fee.

With hundred of thousands of beautiful professionally designed items to choose from this is a bonanza for all app designers, developers and anyone looking for digital assets to use in their projects, particularly, as all downloaded items are covered by a single licence that gives you broad commercial rights when using the items you download.

With so many outstanding resources to choose from at Envato Elements, we though we’d narrow the field for you a little and get you started with 17 wonderful assets to make your mobile apps shine.

Wireframing

1. Mobile Wireframe Kit

Mobile Wireframe Kit

Compatible with Sketch and Illustrator, the Mobile Wireframe Kit features over 90 ready-to-use screens which will give you plenty of flexibility in creating the mobile app of your dreams. The kit has hundreds of symbols and elements which are well labelled and grouped in categories to make them easy to find. Best of all it uses a drag and drop system so you can build your design blueprint quickly and intuitively.

2. Wirey Mobile Wireframe Kit

Wirey Mobile Wireframe Kit

Wirey Mobile Wireframe Kit is another great option for wireframing your mobile app. With over 200 ready-to-use mobile screens, a thousand elements and an easy to use drag and drop system, users can create any number of highly complex projects. All files are compatible with Photoshop and Sketch file formats.  

UI Mobile Kits

3. Dashboard UI Kit

Dashboard UI Kit

Every great mobile app needs an equally great dashboard and Dashboard UI Kit delivers a wide range of screens so that designers can create a range of dashboards from the very simple to the highly complex.  The kit has been designed with sketch and includes a style guide to help you maintain consistency in design.  Another great feature of the kit is that every screen is available for both desktop and mobile.

4. SignUp / Login Mobile Form UI Kit  

SignUp  Login - Mobile Form UI Kit

 SignUp / Login Mobile Form UI Kit is a mobile form kit that providers designers and developers with 40 gorgeous sign-in and sign-up forms for their mobile apps. Each form is highly customisable so that users can change elements like colours and fonts to match the required style. The forms are constructed using vector shapes so that users can easily resize them.

5. Mountify Mobile UI Kit

Mountify Mobile UI Kit

Mountify Mobile UI Kit contains 150 elegant and modern readymade screens for a variety of categories including sign-ins, sign-ups, profiles, shopping carts and so much more. The great thing about Mountify is that all the elements used to create each screen are created using scalable vector shapes which can be swapped and recombined with elements in other screens to suite your tastes and needs without compromising quality.

Fonts

6. Sovereign Typeface

Sovereign Typeface

Need a strong clean font that makes a statement? Sovereign Typeface may be just what you’re looking for. An ideal font for Titles and Headers this big bold font will certain command attention in places where you need it.

7. Burford Pro

Burford Pro

The Burford Pro font package is collection of 18 complementary fonts that can be used separately or layered on top each other to create interesting and unique effects. The package also includes extras like banners, borders, corners, arrows, line breaks, catchwords, anchors and other such items you can use to add visual interest or weight to chosen areas.

8. Shoreline

Shoreline

Shoreline is serif font with a textured surface and a bit of a vintage feel. It comes in regular and bold and is probably best used for in places where you want to create visual emphasis.

Icons

9. 527 Useful Flat Icons

527 Useful Flat Icons

With everything from cameras, globes, and music notes to play buttons, currency signs and much more, 527 Useful Flat Icons will leave you wondering how you ever did without it.  These icons are available in png file format for easy use, as well as ai and eps file formats so that you can change their colour and size to suit your needs.

10. 32 Browser Interface Icons

 32 Browser Interface Icons

The icons in 32 Browser Interface Icons are the kind that every designer should have in their arsenal. This collection covers all the basics like home, favourites, zoom, downloads, refresh, forward and backwards arrow and more. They come in their original vector format so that you can change and customise them as you wish, as well as in png, svg, and psd file formats.

11. White Multipurpose Icons

White Multipurpose Icons

White Multipurpose Icons is a collection designed to stand out against backgrounds that use colour, complex patterns or images. The collection brings together the most popular icons found on the web today like social media icons, shopping cart and magnifying glass icons.

Backgrounds

 12. Royalty-free Stock Photographs

Envato Elements Stock Photographs

Photographs are an important part of branding because they can be manipulated to communicate a wide range of ideas or emotions. A well-chosen photograph can therefore make a huge difference to the success of your project. With your Elements subscription, you can now take advantage of the hundreds of thousands of new royalty-free stock photos available at Envato Elements and take your project to a whole new level.

13. Polygon Abstract Backgrounds

Polygon Abstract Backgrounds

A clean plain background may be the best option for most of your app screens but when you’re looking for a bold and interesting background to set your app apart and catch the viewer’s eye, the stunningPolygon Abstract Backgrounds is a perfect choice.

14. Simple Line Geometric Patterns

Simple Line Geometric Patterns

Simple Line Geometric Patterns will add a clean modern look to your mobile app. The patterns come as vector file and therefore are easy to customise. With 40 different designs to choose from and combine as you like, you’re sure to create an app that stands apart from the pack.

15. Chromasect 02

Chromasect 02

Chromasect 02 certainly has a funky vibe that might not appeal to every taste but used sparingly and strategically, it’s guaranteed to add a touch of cool to your mobile app.  The pack contains 10 unique patterns and comes both in the original vector file and jpg files.

Logos

16. 30 Modern Marks & Symbols

30 Modern Marks  Symbols

Finding the right logo can sometimes be the hardest step in building a product. 30 Modern Marks & Symbols is designed to make your search that much easier. This selection of 30 logos are editable vectors objects which means that you can customise them as you like to add your own unique touch and make them truly yours.

17. 50 Premade Watercolor Logos

50 Premade Watercolor Logos

50 Premade Watercolor Logos is perfect for those projects that convey an air of whimsy or femininity. The logos have a lovely handmade quality to them and are created in layered psd file with links to the font files used so you can easily personalise your selected logo.

Conclusion

So there you have it. 17 digital assets that will help you create beautiful and unique mobile apps.  And the good part is that instead of having to buy 17 separate items and breaking the bank, you can now get all 17 items with one affordable monthly subscription at Envato Elements.  

Better yet, if none of the items I’ve shared with you here catch your fancy, there are thousands more to choose from at Envato Elements and you can download as many as you like for one low monthly price. Now that’s what I call a great deal!

2017-08-29T12:19:05.000Z2017-08-29T12:19:05.000ZNona Blackman

17 Ways to Make Your Mobile App Beautiful With Envato Elements

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/cms-29420

If you are a mobile app developer or interested in getting into designing apps and you haven’t heard of Envato Elements, this post is for you.

Launched just last year, Envato Elements allows you to download unlimited digital assets for a single affordable monthly fee.

With hundred of thousands of beautiful, professionally designed items to choose from, this is a bonanza for all app designers, developers and anyone looking for digital assets to use in their projects, particularly as all downloaded items are covered by a single licence that gives you broad commercial rights when using the items you download.

With so many outstanding resources to choose from at Envato Elements, we thought we’d narrow the field for you a little and get you started with 17 wonderful assets to make your mobile apps shine.

Wireframing

1. Mobile Wireframe Kit

Mobile Wireframe Kit

Compatible with Sketch and Illustrator, the Mobile Wireframe Kit features over 90 ready-to-use screens which will give you plenty of flexibility in creating the mobile app of your dreams. The kit has hundreds of symbols and elements which are well labelled and grouped in categories to make them easy to find. Best of all, it uses a drag and drop system so you can build your design blueprint quickly and intuitively.

2. Wirey Mobile Wireframe Kit

Wirey Mobile Wireframe Kit

Wirey Mobile Wireframe Kit is another great option for wireframing your mobile app. With over 200 ready-to-use mobile screens, a thousand elements and an easy-to-use drag and drop system, users can create any number of highly complex projects. All files are compatible with Photoshop and Sketch file formats.  

Mobile UI Kits

3. Dashboard UI Kit

Dashboard UI Kit

Every great mobile app needs an equally great dashboard, and Dashboard UI Kit delivers a wide range of screens so that designers can create a range of dashboards from the very simple to the highly complex. The kit has been designed with Sketch and includes a style guide to help you maintain consistency in design. Another great feature of the kit is that every screen is available for both desktop and mobile.

4. SignUp / Login Mobile Form UI Kit  

SignUp  Login - Mobile Form UI Kit

SignUp / Login Mobile Form UI Kit is a mobile form kit that provides designers and developers with 40 gorgeous sign-in and sign-up forms for their mobile apps. Each form is highly customisable so that users can change elements like colours and fonts to match the required style. The forms are constructed using vector shapes so that users can easily resize them.

5. Mountify Mobile UI Kit

Mountify Mobile UI Kit

Mountify Mobile UI Kit contains 150 elegant and modern readymade screens for a variety of categories including sign-ins, sign-ups, profiles, shopping carts, and so much more. The great thing about Mountify is that all the elements used to create each screen are created using scalable vector shapes which can be swapped and recombined with elements in other screens to suit your tastes and needs without compromising quality.

Fonts

6. Sovereign Typeface

Sovereign Typeface

Need a strong, clean font that makes a statement? Sovereign Typeface may be just what you’re looking for. An ideal font for titles and headers, this big, bold font will certainly command attention in places where you need it.

7. Burford Pro

Burford Pro

The Burford Pro font package is a collection of 18 complementary fonts that can be used separately or layered on top each other to create interesting and unique effects. The package also includes extras like banners, borders, corners, arrows, line breaks, catchwords, anchors and other such items you can use to add visual interest or weight to chosen areas.

8. Shoreline

Shoreline

Shoreline is a serif font with a textured surface and a bit of a vintage feel. It comes in regular and bold and is probably best used in places where you want to create visual emphasis.

Icons

9. 527 Useful Flat Icons

527 Useful Flat Icons

With everything from cameras, globes, and music notes to play buttons, currency signs and much more, 527 Useful Flat Icons will leave you wondering how you ever did without it.  These icons are available in png file format for easy use, as well as ai and eps file formats so that you can change their colour and size to suit your needs.

10. 32 Browser Interface Icons

 32 Browser Interface Icons

The icons in 32 Browser Interface Icons are the kind that every designer should have in their arsenal. This collection covers all the basics like home, favourites, zoom, downloads, refresh, forward and backwards arrow, and more. They come in their original vector format so that you can change and customise them as you wish, as well as in png, svg, and psd file formats.

11. White Multipurpose Icons

White Multipurpose Icons

White Multipurpose Icons is a collection designed to stand out against backgrounds that use colour, complex patterns, or images. The collection brings together the most popular icons found on the web today, like social media icons, shopping cart and magnifying glass icons.

Backgrounds

12. Royalty-Free Stock Photographs

Envato Elements Stock Photographs

Photographs are an important part of branding because they can be manipulated to communicate a wide range of ideas or emotions. A well-chosen photograph can therefore make a huge difference to the success of your project. With your Elements subscription, you can now take advantage of the hundreds of thousands of new royalty-free stock photos available at Envato Elements and take your project to a whole new level.

13. Polygon Abstract Backgrounds

Polygon Abstract Backgrounds

A clean, plain background may be the best option for most of your app screens, but when you’re looking for a bold and interesting background to set your app apart and catch the viewer’s eye, the stunning Polygon Abstract Backgrounds is a perfect choice.

14. Simple Line Geometric Patterns

Simple Line Geometric Patterns

Simple Line Geometric Patterns will add a clean, modern look to your mobile app. The patterns come as vector files and therefore are easy to customise. With 40 different designs to choose from and combine as you like, you’re sure to create an app that stands apart from the pack.

15. Chromasect 02

Chromasect 02

Chromasect 02 certainly has a funky vibe that might not appeal to every taste, but when used sparingly and strategically, it’s guaranteed to add a touch of cool to your mobile app.  The pack contains ten unique patterns and comes both in the original vector file and jpg files.

Logos

16. 30 Modern Marks & Symbols

30 Modern Marks  Symbols

Finding the right logo can sometimes be the hardest step in building a product. 30 Modern Marks & Symbols is designed to make your search that much easier. This selection of 30 logos is made up of editable vector objects, which means that you can customise them as you like to add your own unique touch and make them truly yours.

17. 50 Premade Watercolor Logos

50 Premade Watercolor Logos

50 Premade Watercolor Logos is perfect for those projects that convey an air of whimsy or femininity. The logos have a lovely handmade quality to them and are created in a layered psd file with links to the font files used so you can easily personalise your selected logo.

Conclusion

So there you have it: 17 digital assets that will help you create beautiful and unique mobile apps. And the good part is that instead of having to buy 17 separate items and breaking the bank, you can now get all 17 items with one affordable monthly subscription at Envato Elements.  

Better yet, if none of the items I’ve shared with you here catch your fancy, there are thousands more to choose from at Envato Elements, and you can download as many as you like for one low monthly price. Now that’s what I call a great deal!

2017-08-29T12:19:05.000Z2017-08-29T12:19:05.000ZNona Blackman

Kotlin From Scratch: Packages and Basic Functions

$
0
0

Kotlin is a modern programming language that compiles to Java bytecode. It is free and open source, and promises to make coding for Android even more fun. 

In the previous article, you learned about ranges and collections in Kotlin. In this tutorial, we'll continue to learn the language by looking at how to organize code using packages, and then go on to an introduction to functions in Kotlin.

1. Packages

If you are familiar with Java, you know that Java uses packages to group related classes; for example, the java.util package has a number of useful utility classes. Packages are declared with the package keyword, and any Kotlin file with a package declaration at the beginning can contain declarations of classes, functions, or interfaces.

Declaration

Looking at the code below, we have declared a package com.chikekotlin.projectx using the package keyword. Also, we declared a class MyClass (we'll discuss classes in Kotlin in future posts) inside this package.

Now, the fully qualified name for the class MyClass is com.chikekotlin.projectx.MyClass.

In the code above, we created a top-level function (we'll get to that shortly). So similarly to MyClass, the fully qualified name for the function saySomething() is com.chikekotlin.projectx.saySomething.

Imports

In Kotlin, we use the import declaration to enable the compiler to locate the classes, functions, interfaces or objects to be imported. In Java, on the other hand, we can't directly import functions or methods—only classes or interfaces. 

We use import to access a function, interface, class or object outside the package where it was declared. 

In the code snippet above, we imported the function saySomething() from a different package, and then we executed that function.

Kotlin also supports wildcard imports using the * operator. This will import all the classes, interfaces and functions declared in the package all at once. This is not recommended, though—it's usually better to make your imports explicit.

Import Aliasing

When you have libraries that have conflicting class or function names (e.g. they each declare a function with the same name), you can use the as keyword to give that imported entity a temporary name.

Note that the temporary name is used only within the file where it was assigned.

2. Functions

A function groups together a series of code statements that perform a task. The details of the implementation of the function are hidden from the caller.

In Kotlin, functions are defined using the fun keyword, as shown in the following example:

In the code above, we defined a simple function hello() with a single parameter name of type String. This function returns a String type. The parameter definition format for functions is name: type, e.g. age: Int, price: Double, student: StudentClass.

The function above is similar to the previous one, but notice that this one has a return type of Unit. Because this function doesn't return any significant value to us—it just prints out a message—its return type is Unit by default. Unit is a Kotlin object (we'll discuss Kotlin objects in later posts) that is similar to the Void types in Java and C.

Note that if you don't explicitly declare the return type to be Unit, the type is inferred by the compiler.

Single-Line Functions

Single-line or one-line functions are functions that are just single expressions. In this function, we get rid of the braces and use the = symbol before the expression. In other words, we get rid of the function block.

The function above can be shortened into a single line:

Looking at the updated function above, you can see that we have made our code more concise by removing the curly braces {}, the return keyword, and also the return type (which is inferred by the compiler). 

You can still include the return type to be more explicit if you want.

Named Parameters

Named parameters allow more readable functions by naming the parameters that are being passed to a function when called.

In the following example, we created a function that prints my full name.

To execute the function above, we would just call it like so:

Looking at the function call above, we don't know which String type arguments equate to which function parameters (though some IDEs such as IntelliJ IDEA can help us). Users of the function will have to look into the function signature (or the source code) or documentation to know what each parameter corresponds to.

In the second function call above, we supplied the parameter names before the argument values. You can see that this function call is clearer and more readable than the previous one. This way of calling functions helps reduce the possibility of bugs that can happen when arguments of the same type are swapped by mistake.

The caller can also alter the order of the parameters using named parameters. For example:

In the code above, we swapped the argument position of the firstName with the lastName. The argument order doesn't matter with named parameters because the compiler will map each of them to the right function parameter.

Default Parameters

In Kotlin, we can give a function default values for any of its parameters. These default values are used if nothing is assigned to the arguments during the function call. To do this in Java, we'd have to create different overloaded methods.

Here, in our calCircumference() method, we modified the method by adding a default value for the pi parameter—Math.PI, a constant from the java.lang.Math package. 

When we call this function, we can either pass our approximated value for pi or use the default. 

Let's see another example.

In the following code, we tried to call the function, but it won't compile:

In the function call above, I'm passing my first name and last name to the function, and hoping to use the default value for the middle name. But this won't compile because the compiler is confused. It doesn't know what the argument "Mgbemena" is for—is it for the middleName or the lastName parameter? 

To solve this issue, we can combine named parameters and default parameters. 

Java Interoperability

Given that Java doesn't support default parameter values in methods, you'll need to specify all the parameter values explicitly when you call a Kotlin function from Java. But Kotlin provides us with the functionality to make it easier for the Java callers by annotating the Kotlin function with @JvmOverloads. This annotation will instruct the Kotlin compiler to generate the Java overloaded functions for us.

In the following example, we annotated the calCirumference() function with @JvmOverloads.

The following code was generated by the Kotlin compiler so that Java callers can then choose which one to call.

In the last generated Java method definition, the pi parameter was omitted. This means that the method will use the default pi value.

Unlimited Arguments

In Java, we can create a method to receive an unspecified number of arguments by including an ellipsis (...) after a type in the method's parameter list. This concept is also supported by Kotlin functions with the use of the vararg modifier followed by the parameter name.

The vararg modifier allows callers to pass in a comma-separated list of arguments. Behind the scenes, this list of arguments will be wrapped into an array. 

When a function has multiple parameters, the vararg parameter is typically the last one. It is also possible to have parameters after the vararg, but you'll need to use named parameters to specify them when you call the function. 

For example, in the code above, the parameter with the vararg modifier is in the last position in a multiple parameters list (this is what we usually do). But what if we don't want it in the last position? In the following example, it is in the second position.

As you can observe in the updated code above, we used named arguments on the last parameter to solve this.

Spread Operator

Let's say we want to pass an array of integers to our printNumbers() function. The function expects the values to be unrolled into a list of parameters, though. If you try to pass the array directly into printNumbers(), you'll see that it won't compile. 

To solve this problem, we need to use the spread operator *. This operator will unpack the array and then pass the individual elements as arguments into the function for us. 

By inserting the spread operator * in front of intsArray in the function's arguments list, the code now compiles and produces the same result as if we had passed the elements of intsArray as a comma-separated list of arguments. 

Return Multiple Values

Sometimes we want to return multiple values from a function. One way is to use the Pair type in Kotlin to create a Pair and then return it. This Pair structure encloses two values that can later be accessed. This Kotlin type can accept any types you supply its constructor. And, what's more, the two types don't even need to be the same. 

In the function above, we constructed a new Pair by passing the userName and userState variables as the first and second arguments respectively to its constructor, and then returned this Pair to the caller.

Another thing to note is that we used a function called require() in the getUserNameAndState() function. This helper function from the standard library is used to give our function callers a precondition to meet, or else an IllegalArgumentException will be thrown (we'll discuss Exceptions in Kotlin in a future post). The optional second argument to require() is a function literal returning a message to be displayed if the exception is thrown. For example, calling the getUserNameAndState() function and passing -1 as an argument to it will trigger:

IntelliJ IDEA code execution result 

Retrieving Data From Pair

In the code above, we accessed the first and second values from the Pair type by using its first and second properties.

However, there is a better way of doing this: destructuring.

What we have done in the updated code above is to directly assign the first and second values of the returned Pair type to the variables name and state respectively. This feature is called destructuring declaration.

Triple Return Values and Beyond

Now, what if you want to return three values at once? Kotlin provides us with another useful type called Triple.

I am sure some of you are wondering what to do if you want to return more than three values. The answer for that will be in a later post, when we discuss Kotlin's data classes.

Conclusion

In this tutorial, you learned about the packages and basic functions in the Kotlin programming language. In the next tutorial in the Kotlin From Scratch series, you'll learn more about functions in Kotlin. See you soon!

To learn more about the Kotlin language, I recommend visiting the Kotlin documentation. Or check out some of our other Android app development posts here on Envato Tuts+!

2017-08-31T10:43:16.453Z2017-08-31T10:43:16.453ZChike Mgbemena

Kotlin From Scratch: Packages and Basic Functions

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/cms-29445

Kotlin is a modern programming language that compiles to Java bytecode. It is free and open source, and promises to make coding for Android even more fun. 

In the previous article, you learned about ranges and collections in Kotlin. In this tutorial, we'll continue to learn the language by looking at how to organize code using packages, and then go on to an introduction to functions in Kotlin.

1. Packages

If you are familiar with Java, you know that Java uses packages to group related classes; for example, the java.util package has a number of useful utility classes. Packages are declared with the package keyword, and any Kotlin file with a package declaration at the beginning can contain declarations of classes, functions, or interfaces.

Declaration

Looking at the code below, we have declared a package com.chikekotlin.projectx using the package keyword. Also, we declared a class MyClass (we'll discuss classes in Kotlin in future posts) inside this package.

Now, the fully qualified name for the class MyClass is com.chikekotlin.projectx.MyClass.

In the code above, we created a top-level function (we'll get to that shortly). So similarly to MyClass, the fully qualified name for the function saySomething() is com.chikekotlin.projectx.saySomething.

Imports

In Kotlin, we use the import declaration to enable the compiler to locate the classes, functions, interfaces or objects to be imported. In Java, on the other hand, we can't directly import functions or methods—only classes or interfaces. 

We use import to access a function, interface, class or object outside the package where it was declared. 

In the code snippet above, we imported the function saySomething() from a different package, and then we executed that function.

Kotlin also supports wildcard imports using the * operator. This will import all the classes, interfaces and functions declared in the package all at once. This is not recommended, though—it's usually better to make your imports explicit.

Import Aliasing

When you have libraries that have conflicting class or function names (e.g. they each declare a function with the same name), you can use the as keyword to give that imported entity a temporary name.

Note that the temporary name is used only within the file where it was assigned.

2. Functions

A function groups together a series of code statements that perform a task. The details of the implementation of the function are hidden from the caller.

In Kotlin, functions are defined using the fun keyword, as shown in the following example:

In the code above, we defined a simple function hello() with a single parameter name of type String. This function returns a String type. The parameter definition format for functions is name: type, e.g. age: Int, price: Double, student: StudentClass.

The function above is similar to the previous one, but notice that this one has a return type of Unit. Because this function doesn't return any significant value to us—it just prints out a message—its return type is Unit by default. Unit is a Kotlin object (we'll discuss Kotlin objects in later posts) that is similar to the Void types in Java and C.

Note that if you don't explicitly declare the return type to be Unit, the type is inferred by the compiler.

Single-Line Functions

Single-line or one-line functions are functions that are just single expressions. In this function, we get rid of the braces and use the = symbol before the expression. In other words, we get rid of the function block.

The function above can be shortened into a single line:

Looking at the updated function above, you can see that we have made our code more concise by removing the curly braces {}, the return keyword, and also the return type (which is inferred by the compiler). 

You can still include the return type to be more explicit if you want.

Named Parameters

Named parameters allow more readable functions by naming the parameters that are being passed to a function when called.

In the following example, we created a function that prints my full name.

To execute the function above, we would just call it like so:

Looking at the function call above, we don't know which String type arguments equate to which function parameters (though some IDEs such as IntelliJ IDEA can help us). Users of the function will have to look into the function signature (or the source code) or documentation to know what each parameter corresponds to.

In the second function call above, we supplied the parameter names before the argument values. You can see that this function call is clearer and more readable than the previous one. This way of calling functions helps reduce the possibility of bugs that can happen when arguments of the same type are swapped by mistake.

The caller can also alter the order of the parameters using named parameters. For example:

In the code above, we swapped the argument position of the firstName with the lastName. The argument order doesn't matter with named parameters because the compiler will map each of them to the right function parameter.

Default Parameters

In Kotlin, we can give a function default values for any of its parameters. These default values are used if nothing is assigned to the arguments during the function call. To do this in Java, we'd have to create different overloaded methods.

Here, in our calCircumference() method, we modified the method by adding a default value for the pi parameter—Math.PI, a constant from the java.lang.Math package. 

When we call this function, we can either pass our approximated value for pi or use the default. 

Let's see another example.

In the following code, we tried to call the function, but it won't compile:

In the function call above, I'm passing my first name and last name to the function, and hoping to use the default value for the middle name. But this won't compile because the compiler is confused. It doesn't know what the argument "Mgbemena" is for—is it for the middleName or the lastName parameter? 

To solve this issue, we can combine named parameters and default parameters. 

Java Interoperability

Given that Java doesn't support default parameter values in methods, you'll need to specify all the parameter values explicitly when you call a Kotlin function from Java. But Kotlin provides us with the functionality to make it easier for the Java callers by annotating the Kotlin function with @JvmOverloads. This annotation will instruct the Kotlin compiler to generate the Java overloaded functions for us.

In the following example, we annotated the calCirumference() function with @JvmOverloads.

The following code was generated by the Kotlin compiler so that Java callers can then choose which one to call.

In the last generated Java method definition, the pi parameter was omitted. This means that the method will use the default pi value.

Unlimited Arguments

In Java, we can create a method to receive an unspecified number of arguments by including an ellipsis (...) after a type in the method's parameter list. This concept is also supported by Kotlin functions with the use of the vararg modifier followed by the parameter name.

The vararg modifier allows callers to pass in a comma-separated list of arguments. Behind the scenes, this list of arguments will be wrapped into an array. 

When a function has multiple parameters, the vararg parameter is typically the last one. It is also possible to have parameters after the vararg, but you'll need to use named parameters to specify them when you call the function. 

For example, in the code above, the parameter with the vararg modifier is in the last position in a multiple parameters list (this is what we usually do). But what if we don't want it in the last position? In the following example, it is in the second position.

As you can observe in the updated code above, we used named arguments on the last parameter to solve this.

Spread Operator

Let's say we want to pass an array of integers to our printNumbers() function. The function expects the values to be unrolled into a list of parameters, though. If you try to pass the array directly into printNumbers(), you'll see that it won't compile. 

To solve this problem, we need to use the spread operator *. This operator will unpack the array and then pass the individual elements as arguments into the function for us. 

By inserting the spread operator * in front of intsArray in the function's arguments list, the code now compiles and produces the same result as if we had passed the elements of intsArray as a comma-separated list of arguments. 

Return Multiple Values

Sometimes we want to return multiple values from a function. One way is to use the Pair type in Kotlin to create a Pair and then return it. This Pair structure encloses two values that can later be accessed. This Kotlin type can accept any types you supply its constructor. And, what's more, the two types don't even need to be the same. 

In the function above, we constructed a new Pair by passing the userName and userState variables as the first and second arguments respectively to its constructor, and then returned this Pair to the caller.

Another thing to note is that we used a function called require() in the getUserNameAndState() function. This helper function from the standard library is used to give our function callers a precondition to meet, or else an IllegalArgumentException will be thrown (we'll discuss Exceptions in Kotlin in a future post). The optional second argument to require() is a function literal returning a message to be displayed if the exception is thrown. For example, calling the getUserNameAndState() function and passing -1 as an argument to it will trigger:

IntelliJ IDEA code execution result 

Retrieving Data From Pair

In the code above, we accessed the first and second values from the Pair type by using its first and second properties.

However, there is a better way of doing this: destructuring.

What we have done in the updated code above is to directly assign the first and second values of the returned Pair type to the variables name and state respectively. This feature is called destructuring declaration.

Triple Return Values and Beyond

Now, what if you want to return three values at once? Kotlin provides us with another useful type called Triple.

I am sure some of you are wondering what to do if you want to return more than three values. The answer for that will be in a later post, when we discuss Kotlin's data classes.

Conclusion

In this tutorial, you learned about the packages and basic functions in the Kotlin programming language. In the next tutorial in the Kotlin From Scratch series, you'll learn more about functions in Kotlin. See you soon!

To learn more about the Kotlin language, I recommend visiting the Kotlin documentation. Or check out some of our other Android app development posts here on Envato Tuts+!

2017-08-31T10:43:16.453Z2017-08-31T10:43:16.453ZChike Mgbemena

Code a Real-Time NativeScript App: Social Login and Firebase

$
0
0

NativeScript is a framework for building cross-platform native mobile apps using XML, CSS, and JavaScript. In this series, we're trying out some of the cool things you can do with a NativeScript app: geolocation and Google Maps integration, SQLite database, Firebase integration, and push notifications. Along the way, we're building a fitness app with real-time capabilities that will use each of these features.

In this tutorial, you'll learn how to add Facebook login to your NativeScript app. You'll also learn how to use Firebase to store walking sessions data in the fitness app. 

What You'll Be Creating

Picking up from the previous tutorial, let's now add the content for the social tab. By default, a button for logging in with Facebook is displayed like this:

not logged in

When a user logs in for the first time, the Facebook app asks for permission to access the public profile and email address:

Facebook permissions

It also asks for the friend list as an added permission. 

Once the user is logged in, the following screen is displayed:

Social tab

This is where the info for the currently logged-in user and the leaderboard for the walking sessions are displayed. Note that only the latest walking session is recorded.

Setting Up the Project

If you have followed the previous post in this series, on SQLite, you can simply use the same project and build the features that we will be adding in this tutorial. Otherwise, you can create a new project and copy the starter files into your project's app folder.

After that, you'll also need to install the geolocation, Google Maps, and SQLite plugins:

Once installed, you need to configure the Google Maps plugin. You can read the complete instructions on how to do this by reading the section on Installing the Google Maps Plugin in this earlier tutorial.

After that, you also need to install fecha, a library for formatting dates: 

Once all that is done, you should be ready to follow along with this tutorial.

Running the Project

You can run the project by executing tns run android. But since this app will use the geolocation functionality, I recommend you use a GPS emulator for quickly setting and changing your location. You can read about how to do so in the section on Running the App in the earlier tutorial.

Setting Up a Firebase App

The first thing that you need to do when working with Firebase is to create a Firebase app. You can do that by going to console.firebase.com and clicking on Add project. Enter the name of the project and click the Create project button. Be sure the name of the project is the same as the name of the app. In this case, the app ID is com.yourname.fitApp so the name of the app is fitApp.

create Firebase project

Once the app is created, you will be redirected to the app's dashboard page. From there you can click on Add Firebase to your Android app, enter the app ID, and click on the Register App button.

Add Firebase to Android app

Next, download the google-services.json file and copy it to the app/App_Resources/android directory. That file contains all the settings needed by the app to communicate with Firebase.

The next step stated in the Firebase dashboard is to include the Firebase SDK. But that's already done in the plugin, so we no longer have to do it.

Setting Up a Facebook App

Since we're going to use Facebook login, we also need to create a Facebook app. Go to developers.facebook.com and create a new Facebook app:

Create Facebook app

Once the app is created, you'll be redirected to the app dashboard. From there, click on the + Add Product menu and select Facebook Login.

Under the Client OAuth Settings, enable everything except Force Web OAuth Reauthentication and Login from Devices. For the Valid OAuth redirect URIs, you can get that by going back to the Firebase dashboard, clicking on Authentication, and enabling Facebook as an authentication method:

Authentication methods

Before you can enable it, you have to enter the Facebook app ID and app secret key. You can get that from the dashboard of the Facebook app you created earlier.

Once that's done, click on Save and copy the OAuth redirect URI over to the Facebook app settings. Don't forget to save the changes.

Next, you also need to add Android as a platform. You can do that by going to the Basic Settings and clicking on Add Platform:

Android settings

Set com.yourname.fitApp as the value for Google Play Package Name and com.tns.NativeScriptActivity for the Class Name.

Note that if you're going to release the app to the app store later on, you will need to generate a hash for the app's .apk file and add it under the key hashes field. Also note that for testing, you will only be able to use the Facebook developer account that you used to create the app. If you want to add other Facebook accounts for testing, you can add them under oles.

Installing the Firebase Plugin

In order to integrate Firebase, we need to install the Firebase plugin for NativeScript. This makes it easier to implement Facebook login and the real-time database feature in Firebase:

Once it's done installing, the installer is going to ask you a few questions regarding the Firebase features that you will use in the app. Answer yes for the Facebook login and no for the rest. 

Configuring Facebook Integration

You need to let the app know which Facebook app it's going to talk to. You can do that by opening the app\App_Resources\Android\AndroidManifest.xml file and adding <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/> under the <application> tag:

Next, create an app\App_Resources\Android\values\facebooklogin.xml file and add the following:

Be sure to replace YOUR_FACEBOOK_APP_ID with the app ID of the Facebook app you created earlier.

Solving Build Errors

If you're getting build errors after installing the plugin, be sure to check the Known issues on Android section in the repo's README. If your specific issue is not there, try to dig through the issues page.

As for me, the main issue that I had was a compatibility issue with the Google Maps plugin. Since that plugin also uses Google Play Services, there was a conflict with different versions being used. To solve that, I had to open the app/App_Resources/Android/app.gradle file and specify the Google Play Services version to use:

At the time of writing of this tutorial, it's at 11.0. But make sure to check which version is currently installed for you via the Android SDK.

Once that's done, you have to uninstall the android platform (tns platform remove android) and try to run the app once again (tns run android).

If that doesn't work for you and you're still getting the same build error, you might need to start all over by creating a new project. But this time, try to install the Firebase plugin before the Google Maps plugin. Then do the necessary configuration changes before trying to run the app.

Adding the Code

Now we're ready to add the code. We'll first add the XML, then the JavaScript, and finally the CSS code.

Adding the UI Markup

We'll be working primarily inside the social tab view. First, add the markup for displaying the info for the currently logged-in user as well as a button for logging out:

Below is the markup for displaying the leaderboard. This loops through the friends_data to display the user name, distance and steps made by the user's friends as well as the user.

If no user is currently logged in, we display the button for logging in with Facebook:

Importing the Libraries

Open the main-view-model.js file and add the following below the code for importing the fecha library:

We're using nativescript-plugin-firebase to talk to Firebase, http to make HTTP requests to Facebook's Graph API, and application-settings to persist the user's login data.

Initializing Firebase

Next, initialize Firebase with the init() function. This accepts an object which contains options for the different features supported by Firebase (e.g. authentication, real-time database, cloud messaging). 

Below, we're adding the persist option, which makes Firebase save data locally so the app can still be used while offline. Later on, we'll be adding the listener for when the authentication status changes (when the user logs in or logs out of the app).

Logging a User In

Next, add the code that will be executed when the user taps on the button for logging in to Facebook. This uses the login function, which accepts an object containing the type and facebookOptions

The type is the authentication method to be used for logging in. In this case, it's Facebook. facebookOptions is an object containing an array named scope. The elements of this array are the permissions that you want the app to request from the user. 

Once the user has logged in and agreed to all the permissions being requested, the promise resolves and executes the first function passed to then(). The Facebook user details are passed as an argument to this function, but the only thing we need is the access token. We can use this later to make requests to Facebook's Graph API in order to get additional information.

Next, we'll issue a query to the Firebase database to check if the user already exists or not. For this, we use the query() method. This accepts the function to execute when a response is returned as the first argument. The second argument is the path in which the query is performed, and the third is the query itself. 

If the user already exists, query() will return the user's data. We then save the data locally using application settings. We'll be needing to access this data later when we listen for auth status changes, and when we update the latest walking session of the user on Firebase.

Create a New User

Now let's add the code for saving the data for a new user. Start by creating the object which contains the user data. Then make a request to Facebook's Graph API to get the user's Facebook ID (which is valid for this specific app only). 

Later on, we will be using this ID to check if a specific Firebase user is a friend of the current user. Firebase doesn't return this ID when you log in, which is why we need to make a separate request. 

Once a response is returned, we'll use Firebase's push() method to save the user's data in the /users path. This returns the key which serves as the ID for this specific user. We're going to use it later to update the user's last walking session. That's why we also need to save it locally along with the user's data and the Facebook access token.

Now that we've added the code for logging a user in, the next step is to go back to the firebase.init() call, and add onAuthStateChanged. This function will get executed every time the auth status changes (when a user logs in or out). If a user is logged in, we want to update the UI to show the current user. 

Note that we're wrapping it inside setTimeout() with a five-second delay because it takes a few seconds after logging in for the user's data (Firebase user key, Firebase user, and Facebook Access Token) to be available. 

Next, we add the code for getting the user's friends. The graph API returns the ID and the name for each of the user's friends, but we only need the IDs. We also need to push the ID for the current user since we're going to display it in the leaderboard as well.

Displaying the Leaderboard

Next, add the code for listening for changes in the database. Up until now, we haven't really implemented the "real-time" part of this app. This is the time when we finally add it. 

For this, we use the addValueEventListener() method. This accepts the function that you want to execute when a change is made to the path you specified as a second argument. The whole value (result) is passed in as an argument to this function. 

There's really no functionality to specify a query to only filter the result by specific IDs. So using the array of friend IDs (friends_ids), we loop through the result and check if the current row is the current user or one of their friends. Only then do we push the value for the current row. From there, we just sort and format the data for displaying in the UI.

Updating the Latest Walking Session

When the user stops tracking their current location, we update the distance and steps of the user on Firebase:

Logging the User Out

Next, add the code for logging the user out. This resets the UI to a state where the user isn't logged in, and it also clears out the local data.

Adding the Styles

Finally, open the app/app.css file and add the following below the existing code:

Conclusion

That's it! In this tutorial you've learned how to integrate Facebook login and Firebase into a NativeScript app. As you might have noticed in the documentation for the NativeScript Firebase plugin, you can actually do a lot more with this plugin. In fact, we will be using its Cloud Messaging feature in order to implement the last feature for this app: Push Notifications. So stay tuned for that!

And in the meantime, check out some of our other posts on NativeScript and cross-platform mobile apps!

2017-09-01T14:00:00.000Z2017-09-01T14:00:00.000ZWernher-Bel Ancheta

Code a Real-Time NativeScript App: Social Login and Firebase

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/cms-29413

NativeScript is a framework for building cross-platform native mobile apps using XML, CSS, and JavaScript. In this series, we're trying out some of the cool things you can do with a NativeScript app: geolocation and Google Maps integration, SQLite database, Firebase integration, and push notifications. Along the way, we're building a fitness app with real-time capabilities that will use each of these features.

In this tutorial, you'll learn how to add Facebook login to your NativeScript app. You'll also learn how to use Firebase to store walking sessions data in the fitness app. 

What You'll Be Creating

Picking up from the previous tutorial, let's now add the content for the social tab. By default, a button for logging in with Facebook is displayed like this:

not logged in

When a user logs in for the first time, the Facebook app asks for permission to access the public profile and email address:

Facebook permissions

It also asks for the friend list as an added permission. 

Once the user is logged in, the following screen is displayed:

Social tab

This is where the info for the currently logged-in user and the leaderboard for the walking sessions are displayed. Note that only the latest walking session is recorded.

Setting Up the Project

If you have followed the previous post in this series, on SQLite, you can simply use the same project and build the features that we will be adding in this tutorial. Otherwise, you can create a new project and copy the starter files into your project's app folder.

After that, you'll also need to install the geolocation, Google Maps, and SQLite plugins:

Once installed, you need to configure the Google Maps plugin. You can read the complete instructions on how to do this by reading the section on Installing the Google Maps Plugin in this earlier tutorial.

After that, you also need to install fecha, a library for formatting dates: 

Once all that is done, you should be ready to follow along with this tutorial.

Running the Project

You can run the project by executing tns run android. But since this app will use the geolocation functionality, I recommend you use a GPS emulator for quickly setting and changing your location. You can read about how to do so in the section on Running the App in the earlier tutorial.

Setting Up a Firebase App

The first thing that you need to do when working with Firebase is to create a Firebase app. You can do that by going to console.firebase.com and clicking on Add project. Enter the name of the project and click the Create project button. Be sure the name of the project is the same as the name of the app. In this case, the app ID is com.yourname.fitApp so the name of the app is fitApp.

create Firebase project

Once the app is created, you will be redirected to the app's dashboard page. From there you can click on Add Firebase to your Android app, enter the app ID, and click on the Register App button.

Add Firebase to Android app

Next, download the google-services.json file and copy it to the app/App_Resources/android directory. That file contains all the settings needed by the app to communicate with Firebase.

The next step stated in the Firebase dashboard is to include the Firebase SDK. But that's already done in the plugin, so we no longer have to do it.

Setting Up a Facebook App

Since we're going to use Facebook login, we also need to create a Facebook app. Go to developers.facebook.com and create a new Facebook app:

Create Facebook app

Once the app is created, you'll be redirected to the app dashboard. From there, click on the + Add Product menu and select Facebook Login.

Under the Client OAuth Settings, enable everything except Force Web OAuth Reauthentication and Login from Devices. For the Valid OAuth redirect URIs, you can get that by going back to the Firebase dashboard, clicking on Authentication, and enabling Facebook as an authentication method:

Authentication methods

Before you can enable it, you have to enter the Facebook app ID and app secret key. You can get that from the dashboard of the Facebook app you created earlier.

Once that's done, click on Save and copy the OAuth redirect URI over to the Facebook app settings. Don't forget to save the changes.

Next, you also need to add Android as a platform. You can do that by going to the Basic Settings and clicking on Add Platform:

Android settings

Set com.yourname.fitApp as the value for Google Play Package Name and com.tns.NativeScriptActivity for the Class Name.

Note that if you're going to release the app to the app store later on, you will need to generate a hash for the app's .apk file and add it under the key hashes field. Also note that for testing, you will only be able to use the Facebook developer account that you used to create the app. If you want to add other Facebook accounts for testing, you can add them under oles.

Installing the Firebase Plugin

In order to integrate Firebase, we need to install the Firebase plugin for NativeScript. This makes it easier to implement Facebook login and the real-time database feature in Firebase:

Once it's done installing, the installer is going to ask you a few questions regarding the Firebase features that you will use in the app. Answer yes for the Facebook login and no for the rest. 

Configuring Facebook Integration

You need to let the app know which Facebook app it's going to talk to. You can do that by opening the app\App_Resources\Android\AndroidManifest.xml file and adding <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/> under the <application> tag:

Next, create an app\App_Resources\Android\values\facebooklogin.xml file and add the following:

Be sure to replace YOUR_FACEBOOK_APP_ID with the app ID of the Facebook app you created earlier.

Solving Build Errors

If you're getting build errors after installing the plugin, be sure to check the Known issues on Android section in the repo's README. If your specific issue is not there, try to dig through the issues page.

As for me, the main issue that I had was a compatibility issue with the Google Maps plugin. Since that plugin also uses Google Play Services, there was a conflict with different versions being used. To solve that, I had to open the app/App_Resources/Android/app.gradle file and specify the Google Play Services version to use:

At the time of writing of this tutorial, it's at 11.0. But make sure to check which version is currently installed for you via the Android SDK.

Once that's done, you have to uninstall the android platform (tns platform remove android) and try to run the app once again (tns run android).

If that doesn't work for you and you're still getting the same build error, you might need to start all over by creating a new project. But this time, try to install the Firebase plugin before the Google Maps plugin. Then do the necessary configuration changes before trying to run the app.

Adding the Code

Now we're ready to add the code. We'll first add the XML, then the JavaScript, and finally the CSS code.

Adding the UI Markup

We'll be working primarily inside the social tab view. First, add the markup for displaying the info for the currently logged-in user as well as a button for logging out:

Below is the markup for displaying the leaderboard. This loops through the friends_data to display the user name, distance and steps made by the user's friends as well as the user.

If no user is currently logged in, we display the button for logging in with Facebook:

Importing the Libraries

Open the main-view-model.js file and add the following below the code for importing the fecha library:

We're using nativescript-plugin-firebase to talk to Firebase, http to make HTTP requests to Facebook's Graph API, and application-settings to persist the user's login data.

Initializing Firebase

Next, initialize Firebase with the init() function. This accepts an object which contains options for the different features supported by Firebase (e.g. authentication, real-time database, cloud messaging). 

Below, we're adding the persist option, which makes Firebase save data locally so the app can still be used while offline. Later on, we'll be adding the listener for when the authentication status changes (when the user logs in or logs out of the app).

Logging a User In

Next, add the code that will be executed when the user taps on the button for logging in to Facebook. This uses the login function, which accepts an object containing the type and facebookOptions

The type is the authentication method to be used for logging in. In this case, it's Facebook. facebookOptions is an object containing an array named scope. The elements of this array are the permissions that you want the app to request from the user. 

Once the user has logged in and agreed to all the permissions being requested, the promise resolves and executes the first function passed to then(). The Facebook user details are passed as an argument to this function, but the only thing we need is the access token. We can use this later to make requests to Facebook's Graph API in order to get additional information.

Next, we'll issue a query to the Firebase database to check if the user already exists or not. For this, we use the query() method. This accepts the function to execute when a response is returned as the first argument. The second argument is the path in which the query is performed, and the third is the query itself. 

If the user already exists, query() will return the user's data. We then save the data locally using application settings. We'll be needing to access this data later when we listen for auth status changes, and when we update the latest walking session of the user on Firebase.

Create a New User

Now let's add the code for saving the data for a new user. Start by creating the object which contains the user data. Then make a request to Facebook's Graph API to get the user's Facebook ID (which is valid for this specific app only). 

Later on, we will be using this ID to check if a specific Firebase user is a friend of the current user. Firebase doesn't return this ID when you log in, which is why we need to make a separate request. 

Once a response is returned, we'll use Firebase's push() method to save the user's data in the /users path. This returns the key which serves as the ID for this specific user. We're going to use it later to update the user's last walking session. That's why we also need to save it locally along with the user's data and the Facebook access token.

Now that we've added the code for logging a user in, the next step is to go back to the firebase.init() call, and add onAuthStateChanged. This function will get executed every time the auth status changes (when a user logs in or out). If a user is logged in, we want to update the UI to show the current user. 

Note that we're wrapping it inside setTimeout() with a five-second delay because it takes a few seconds after logging in for the user's data (Firebase user key, Firebase user, and Facebook Access Token) to be available. 

Next, we add the code for getting the user's friends. The graph API returns the ID and the name for each of the user's friends, but we only need the IDs. We also need to push the ID for the current user since we're going to display it in the leaderboard as well.

Displaying the Leaderboard

Next, add the code for listening for changes in the database. Up until now, we haven't really implemented the "real-time" part of this app. This is the time when we finally add it. 

For this, we use the addValueEventListener() method. This accepts the function that you want to execute when a change is made to the path you specified as a second argument. The whole value (result) is passed in as an argument to this function. 

There's really no functionality to specify a query to only filter the result by specific IDs. So using the array of friend IDs (friends_ids), we loop through the result and check if the current row is the current user or one of their friends. Only then do we push the value for the current row. From there, we just sort and format the data for displaying in the UI.

Updating the Latest Walking Session

When the user stops tracking their current location, we update the distance and steps of the user on Firebase:

Logging the User Out

Next, add the code for logging the user out. This resets the UI to a state where the user isn't logged in, and it also clears out the local data.

Adding the Styles

Finally, open the app/app.css file and add the following below the existing code:

Conclusion

That's it! In this tutorial you've learned how to integrate Facebook login and Firebase into a NativeScript app. As you might have noticed in the documentation for the NativeScript Firebase plugin, you can actually do a lot more with this plugin. In fact, we will be using its Cloud Messaging feature in order to implement the last feature for this app: Push Notifications. So stay tuned for that!

And in the meantime, check out some of our other posts on NativeScript and cross-platform mobile apps!

2017-09-01T14:00:00.000Z2017-09-01T14:00:00.000ZWernher-Bel Ancheta

Serverless Logic With Realm Functions

$
0
0
Final product image
What You'll Be Creating

In the previous tutorials, we took a look at the Realm Platform as well as the on-device Realm Database for iOS. In that post, you learned how to synchronize your app data locally as well as in the cloud. While this presents a complete solution for many developers, you may want to do more than just persist data, but also run server-side logic. 

This year, Realm added the ability to create serverless functionality via Realm Functions, allowing developers to create program logic to respond to database events automatically.

Realm’s serverless computing solution is akin to Amazon’s AWS Lambda or Microsoft’s Azure Functions. Like them, it allows you to run code without having to provision your own servers. Your functions will run on Realm Object Server. Realm Functions provide the chance to write JavaScript-powered functions that react to Realm’s live objects and manage them through the Realm dashboard interface. 

Whether you need to react to live-objects and send a push notification to users or trigger an API call to another third-party vendor SDK like Twilio, reactive events via functions allow you to respond and react server-side. In this tutorial, you are going to learn how to work with Realm Functions.

Objectives of This Tutorial

In this tutorial, you'll learn how to implement and work with Realm Functions to create a sample trigger function that will update a value in our cloud database. This will be a contrived example, but you can apply this knowledge to more practical problems. 

In this tutorial, we will be covering the following:

  • event handling and functions
  • reasons to use functions
  • creating functions from the dashboard
  • integrating functions into your Realm Object Server.

Assumed Knowledge

This tutorial assumes you’ve read through the previous two tutorials in this series. As Realm Functions are written in JavaScript, you should also have a basic understanding of that language, although you don't need to be an expert. 

If you want a primer on Realm, check out the previous posts in this series.

What Are Realm Functions? 

In the previous tutorials you've used Realm to create on-device persistence, as well as synchronizing user data with the cloud, but one notable absence has been in the ability to work intelligently with data server-side. We sometimes need server-side logic that can respond to changes in the data, the same way triggers work in traditional databases. 

This is where Realm Functions come in, providing the ability to anticipate and react to changes in Realms. Realm Functions also empowered teams to create server-side logic without needing a dedicated back-end developer, building on top of the Realm Platform with minimal configuration, and without having to worry about serialization or adding additional endpoints to the server. 

Realm Functions is our “serverless” app logic layer, where you can easily build server-side features with simple JavaScript, no backend team required. When synced data changes, your custom logic executes—making it fast and easy for mobile developers to build and ship sophisticated server-dependent features. — Realm.io

Event Handling in Realm

Functions handle events through the Realm Object Server with Node.js functions which are subsequently called by the Realm Object Server global listening API, which passes changeEvent() objects triggered via the function logic. This is accomplished through the server-side Node.js instance, which connects to the global event listener API, allowing developers to observe for changes across Realms and filtering for specific Realms that match a specific Regex pattern. 

Developers can therefore listen to specific and unique Realm paths which may be set up for specific users, and then react to those user's changes. The global event listener then triggers a notification for the server-side functions to respond to the changes. 

The notification packet informs the event handlers about the virtual path of the updated Realm, as well as the Realm object or objects that have changed. These are broken down by class name and object indexes modified during the last synchronization transaction. 

Creating a Realm Event Handling function involves creating a small Node.js application, with a package.json to define the application and its dependencies. For more information on creating event handlers in Realm Object Server, refer to the Realm Guidelines on Event Handling

Next, we'll start setting up our first Realm function. 

Setting Up Your First Realm Function

For the purposes of this tutorial, we are going to focus on a simple function example to illustrate how functions are created and integrated into the Realm Mobile Platform. It is assumed you already have the existing application from the previous tutorials, hosted on your Realm Object Server and running, before proceeding with the rest of this tutorial. 

First, head off to the Realm Object Server dashboard and select the Functions tab. On this page, Realm already provides you with a sample function that you can enable and run quickly, by first naming the function, choosing which Realm to apply it to (our working app in this case, RealmDoApp), and then starting the function event listener by pressing the Start button. 

Starting a function event listener

Go ahead and do that, while running your iOS app in Xcode Simulator, and create a new reminder task. You will notice the log below is populating with log messages for the different states of your app.

log messages showing the different states of your app

Let’s take a look at the sample code in greater detail: 

The function starts off by exposing the event handing method through exports. Event handling functions take a changeEvent as their parameter. This simple function just outputs the changeEvent.path to the console, showing what is being changed exactly. 

We then get a reference to the changed realm through the changeEvent object, and then get a list of objects and changes. We output a record of all the insertions, modifications, and deletions to the console. 

Extending the Simple Function

This sample function isn't really functional, but in order to solidify our understanding of what it is possible to do with functions, let's take the function a bit further and customize it. 

Since it's a Node.js application, we can work with third-party Node.js libraries. In this instance, we'll use a library called libphonenumber, and modify our function to parse entries as phone numbers, with the correct formatting and international prefix. 

Before entering the code below, install the third-party library by entering the following into the Realm Object Server:

npm install google-libphonenumber --save

Press Stop in the console to stop the function running, and then modify the function with the following code:

In the above code, we're creating an instance reference to the third-party library google-libphonenumber, and then getting a list of the reminder objects via realm.objects("Reminder"). Then we get a reference to the last reminder in the array, as it is the most recent one, and then convert its data to a phone number. 

We'll output the result of that to the console, before actually writing the formatted version of the data back to realm, via:

Give the function another spin by restarting it, and in the iOS Simulator, enter a phone number that isn't formatted quite correctly, say 17187998177. Through the console log and final output on the app, it should format the number correctly using the third-party library, with the spacing and international prefix as follows:

+1 718-799 8177

What we are seeing here is a serverless way of triggering an event for a change (insertion) and formatting the data prior to persisting it to the cloud.

Specifying Realm URL Path Regular Expressions

In our dashboard function, we simply pointed to a specific Realm application, RealmDo, but you can also define a regular expression (regex) to more uniquely distinguish which paths trigger the function. To match for all Realms, you would use .* (which matches zero or more of any character). Or you could match a user-owned Realm with ^/([0-9a-f]+)/Reminder$.

Conclusion

Realm Functions create new possibilities for the Realm Mobile Platform by providing a simple and elegant way to add serverless logic that is capable of responding to changes in Realms. Through the Dashboard, developers can create functions that respond to changes across all Realms, or just on specific paths. 

In this tutorial, you learned a bit about what Realm Functions are, and how they provide a holistic development environment not only for creating and persisting data but also for adding logic to it. We extended the default function and called a third-party JavaScript library to convert phone numbers. 

While our example is a bit contrived, it provides you with an idea of what you can do to manage Realm objects as they are inserted, modified or deleted. This is just like how traditional databases leverage triggers, only server-less and with minimal code, as you can see. 

While you're here, take a look at some of our other iOS development posts here on Envato Tuts+.

2017-09-04T15:00:00.000Z2017-09-04T15:00:00.000ZDoron Katz

Serverless Logic With Realm Functions

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/cms-29470
Final product image
What You'll Be Creating

In the previous tutorials, we took a look at the Realm Platform as well as the on-device Realm Database for iOS. In that post, you learned how to synchronize your app data locally as well as in the cloud. While this presents a complete solution for many developers, you may want to do more than just persist data, but also run server-side logic. 

This year, Realm added the ability to create serverless functionality via Realm Functions, allowing developers to create program logic to respond to database events automatically.

Realm’s serverless computing solution is akin to Amazon’s AWS Lambda or Microsoft’s Azure Functions. Like them, it allows you to run code without having to provision your own servers. Your functions will run on Realm Object Server. Realm Functions provide the chance to write JavaScript-powered functions that react to Realm’s live objects and manage them through the Realm dashboard interface. 

Whether you need to react to live-objects and send a push notification to users or trigger an API call to another third-party vendor SDK like Twilio, reactive events via functions allow you to respond and react server-side. In this tutorial, you are going to learn how to work with Realm Functions.

Objectives of This Tutorial

In this tutorial, you'll learn how to implement and work with Realm Functions to create a sample trigger function that will update a value in our cloud database. This will be a contrived example, but you can apply this knowledge to more practical problems. 

In this tutorial, we will be covering the following:

  • event handling and functions
  • reasons to use functions
  • creating functions from the dashboard
  • integrating functions into your Realm Object Server.

Assumed Knowledge

This tutorial assumes you’ve read through the previous two tutorials in this series. As Realm Functions are written in JavaScript, you should also have a basic understanding of that language, although you don't need to be an expert. 

If you want a primer on Realm, check out the previous posts in this series.

What Are Realm Functions? 

In the previous tutorials you've used Realm to create on-device persistence, as well as synchronizing user data with the cloud, but one notable absence has been in the ability to work intelligently with data server-side. We sometimes need server-side logic that can respond to changes in the data, the same way triggers work in traditional databases. 

This is where Realm Functions come in, providing the ability to anticipate and react to changes in Realms. Realm Functions also empowered teams to create server-side logic without needing a dedicated back-end developer, building on top of the Realm Platform with minimal configuration, and without having to worry about serialization or adding additional endpoints to the server. 

Realm Functions is our “serverless” app logic layer, where you can easily build server-side features with simple JavaScript, no backend team required. When synced data changes, your custom logic executes—making it fast and easy for mobile developers to build and ship sophisticated server-dependent features. — Realm.io

Event Handling in Realm

Functions handle events through the Realm Object Server with Node.js functions which are subsequently called by the Realm Object Server global listening API, which passes changeEvent() objects triggered via the function logic. This is accomplished through the server-side Node.js instance, which connects to the global event listener API, allowing developers to observe for changes across Realms and filtering for specific Realms that match a specific Regex pattern. 

Developers can therefore listen to specific and unique Realm paths which may be set up for specific users, and then react to those user's changes. The global event listener then triggers a notification for the server-side functions to respond to the changes. 

The notification packet informs the event handlers about the virtual path of the updated Realm, as well as the Realm object or objects that have changed. These are broken down by class name and object indexes modified during the last synchronization transaction. 

Creating a Realm Event Handling function involves creating a small Node.js application, with a package.json to define the application and its dependencies. For more information on creating event handlers in Realm Object Server, refer to the Realm Guidelines on Event Handling

Next, we'll start setting up our first Realm function. 

Setting Up Your First Realm Function

For the purposes of this tutorial, we are going to focus on a simple function example to illustrate how functions are created and integrated into the Realm Mobile Platform. It is assumed you already have the existing application from the previous tutorials, hosted on your Realm Object Server and running, before proceeding with the rest of this tutorial. 

First, head off to the Realm Object Server dashboard and select the Functions tab. On this page, Realm already provides you with a sample function that you can enable and run quickly, by first naming the function, choosing which Realm to apply it to (our working app in this case, RealmDoApp), and then starting the function event listener by pressing the Start button. 

Starting a function event listener

Go ahead and do that, while running your iOS app in Xcode Simulator, and create a new reminder task. You will notice the log below is populating with log messages for the different states of your app.

log messages showing the different states of your app

Let’s take a look at the sample code in greater detail: 

The function starts off by exposing the event handing method through exports. Event handling functions take a changeEvent as their parameter. This simple function just outputs the changeEvent.path to the console, showing what is being changed exactly. 

We then get a reference to the changed realm through the changeEvent object, and then get a list of objects and changes. We output a record of all the insertions, modifications, and deletions to the console. 

Extending the Simple Function

This sample function isn't really functional, but in order to solidify our understanding of what it is possible to do with functions, let's take the function a bit further and customize it. 

Since it's a Node.js application, we can work with third-party Node.js libraries. In this instance, we'll use a library called libphonenumber, and modify our function to parse entries as phone numbers, with the correct formatting and international prefix. 

Before entering the code below, install the third-party library by entering the following into the Realm Object Server:

npm install google-libphonenumber --save

Press Stop in the console to stop the function running, and then modify the function with the following code:

In the above code, we're creating an instance reference to the third-party library google-libphonenumber, and then getting a list of the reminder objects via realm.objects("Reminder"). Then we get a reference to the last reminder in the array, as it is the most recent one, and then convert its data to a phone number. 

We'll output the result of that to the console, before actually writing the formatted version of the data back to realm, via:

Give the function another spin by restarting it, and in the iOS Simulator, enter a phone number that isn't formatted quite correctly, say 17187998177. Through the console log and final output on the app, it should format the number correctly using the third-party library, with the spacing and international prefix as follows:

+1 718-799 8177

What we are seeing here is a serverless way of triggering an event for a change (insertion) and formatting the data prior to persisting it to the cloud.

Specifying Realm URL Path Regular Expressions

In our dashboard function, we simply pointed to a specific Realm application, RealmDo, but you can also define a regular expression (regex) to more uniquely distinguish which paths trigger the function. To match for all Realms, you would use .* (which matches zero or more of any character). Or you could match a user-owned Realm with ^/([0-9a-f]+)/Reminder$.

Conclusion

Realm Functions create new possibilities for the Realm Mobile Platform by providing a simple and elegant way to add serverless logic that is capable of responding to changes in Realms. Through the Dashboard, developers can create functions that respond to changes across all Realms, or just on specific paths. 

In this tutorial, you learned a bit about what Realm Functions are, and how they provide a holistic development environment not only for creating and persisting data but also for adding logic to it. We extended the default function and called a third-party JavaScript library to convert phone numbers. 

While our example is a bit contrived, it provides you with an idea of what you can do to manage Realm objects as they are inserted, modified or deleted. This is just like how traditional databases leverage triggers, only server-less and with minimal code, as you can see. 

While you're here, take a look at some of our other iOS development posts here on Envato Tuts+.

2017-09-04T15:00:00.000Z2017-09-04T15:00:00.000ZDoron Katz

How to Submit an iOS App to the App Store

$
0
0

You have worked weeks or months on your first iOS application, and you are ready to submit your masterpiece to Apple's App Store. How do you do this? Is your application ready for submission? I am sure that some of these questions have entered your mind at one point or another. 

Is submitting an application as simple as sending Apple your application's binary? Not quite. With this tutorial, I will provide you with a detailed map to get your application submitted to Apple's App Store.

Introduction

Even though the App Store review process is a black box for the most part, that doesn't mean that you can't prepare yourself and your application for Apple's review process. Apple provides guidelines to help you stay within the sometimes invisible boundaries of what is and isn't allowed in the App Store.

The first time you submit an application to the App Store is exciting and nerve-racking at the same time. Even for experienced iOS developers, submitting an application to the App Store is often a stressful undertaking because it is something that most developers don't do on a daily basis.

Throughout this article, I am assuming that you are a registered iOS developer, which means that you are enrolled in Apple's iOS Developer Program and are allowed to submit applications for publication in the App Store. To submit an iOS application to the App Store, you need to be a registered iOS developer. Red flag? Don't worry. You can enroll in Apple's iOS Developer Program by visiting the Apple Developer page and clicking the Enroll button. 

Enrolling in Apples iOS Developer Program

1. Is Your Application Ready?

Step 1: Testing

An application isn't necessarily ready when you've written the last line of code or implemented the final feature of the application's specification. 

Have you tested your application on one or more physical devices? Have you profiled your application for memory leaks and performance issues? Does your application crash from time to time? 

The family of iOS devices has grown substantially over the years, and it is important to test your application on as many iOS devices as you can lay your hands on. Common issues include not optimizing an application for certain screen sizes. The iOS Simulator is a great tool, but it runs on your Mac, which has more memory and processing power than the phone in your pocket. 

Apple's Review Process isn't airtight, but it is very capable of identifying problems that might affect your application's user experience. If your application crashes from time to time or it becomes slow after ten minutes of use, then you have some work to do before submitting it to the App Store. 

Even if Apple's review team doesn't spot the problem, your users will. If the people using your application are not pleased, they will leave bad reviews on the App Store, which may harm sales or inhibit downloads.

Step 2: Rules and Guidelines

As I mentioned earlier, Apple provides developers with a number of documents that are a great help during the creation and development process of your application. 

The documents that you should be aware of are the iOS Human Interface Guidelines and the App Store Review Guidelines. Despite the availability of these documents, it seems that few developers take the time to browse them, let alone read them. It shouldn't be a surprise that some applications are therefore rejected even though the reason for the rejection is clearly stated in these documents.

Even if you don't intend to read the iOS Human Interface Guidelines or the App Store Review Guidelines, it is important to know some of the rules that they talk about. Take a look at the short list below to get an idea of what your application should and shouldn't do.

Your application:

  • shouldn't crash
  • shouldn't use private APIs
  • shouldn't replicate the functionality of native applications
  • should use In App Purchase for in-app (financial) transactions
  • shouldn't use the camera or microphone without the user's knowledge
  • should only use artwork that is your copyright or that you have permission to use

Keep in mind that this is a tiny subset of the guidelines included in the aforementioned documents. The majority of the rules and guidelines are trivial, but some are not, and you might even violate some of them inadvertently. 

Let me give you an example. Before Apple started using its own maps (a really long time ago), the MapKit framework used Google's maps. This was clear to the user because of the small Google logo in the bottom left corner of each map. However, if some part of your application's user interface covered or obscured Google's logo, your application would get rejected. This rule seems trivial, but it is a rule that is easily violated if you're not careful. Even automated tests won't cover you in this case.


2. Prerequisites

Before you can even start thinking about submitting your application to the App Store, you need to make sure that you have an App ID, a valid distribution certificate, and a valid provisioning profile. Let me show you what this entails.

Step 1: App ID

Every application needs an App ID or application identifier. There are two types of application identifiers: an explicit App ID and a wildcard App ID. A wildcard App ID can be used for building and installing multiple applications. Despite the convenience of a wildcard App ID, an explicit App ID is required if your application uses iCloud or makes use of other iOS features, such as Game Center, Apple Push Notifications, or In App Purchase.

If you're not sure what App ID best fits your project, then I recommend reading Technical Note QA1713 for more information about the topic.

Step 2: Distribution Certificate

To submit an application to the App Store, you need to create an iOS provisioning profile for distribution. To create such a provisioning profile, you first need to create a distribution certificate. The process for creating a distribution certificate is very similar to creating a development certificate. If you have tested your application on a physical device, then you are probably already familiar with the creation of a development certificate.

If you need to refresh your memory, I suggest reading Apple's guide, Code Signing your Apps, about signing certificates and provisioning profiles. The process is not difficult once you understand how the various pieces of the puzzle fit together.

Step 3: Provisioning Profile

Once you've created an App ID and a distribution certificate, you can create an iOS provisioning profile for distributing your application through the App Store. 

Keep in mind that you cannot use the same provisioning profile that you use for ad hoc distribution. You need to create a separate provisioning profile for App Store distribution. If you use a wildcard App ID for your project, then you can use the same provisioning profile for multiple applications.

Step 4: Build Settings

With the App ID, distribution certificate, and provisioning profile in place, it is time to configure your target's build settings in Xcode. This means selecting the target from the list of targets in Xcode's Project Navigator, opening the Build Settings tab at the top, and updating the settings in the Signing section. You will need to set the Code Signing to Automatic. 

Configuring the Targets Build Settings

Even though the code signing process is fairly simple once you understand it, it is something that trips up a lot of developers. I don't know a single Cocoa developer who hasn't run into code signing issues at some point in their career. Once you've cleared this hurdle, the rest of the submission process is fairly easy.

Step 5: Deployment Target

It is useful to think a little about your application's deployment target. Each target in an Xcode project has a deployment target, which indicates the minimum version of the operating system that the application can run on. 

It is up to you to set the deployment target, but keep in mind that modifying the deployment target is not something you can do without consequences once your application is in the App Store. If you increase the deployment target for an update of your application, then users who have already purchased your application but don't meet the new deployment target cannot run the update. 

It gets really problematic when a user downloads an update through iTunes (not the device), replacing the previous version on their computer, and then discovers that the new update doesn't run on their device.

I have two very simple tips with regards to your application's deployment target:

  1. Be very careful when you decide to increase the deployment target of an existing application. Mention this in the application's release notes of the updates that precede the change, and again in the update that uses the new deployment target. If you warn your customers well in advance, you have done all you can to prevent potential problems. 
  2. For new applications, I almost always set the deployment target to the last major release.

3. Assets

Step 1: Icons

You probably know that an application icon is a vital component of every iOS application, but you need to make sure that your application ships with the correct sizes of the artwork. Take a look at the table below: 

Image Size (px)

File Name

Used For

App Store

Ad Hoc

512x512

iTunesArtwork

App list in iTunes

Do not include

Optional but recommended

1024x1024

iTunesArtwork@2x

App list in iTunes for devices with retina display

Do not include

Optional but recommended

120x120

Icon-60@2x.png

Home screen on iPhone/iPod Touch with retina display

Required

Required

180x180

Icon-60@3x.png

Home screen on iPhone with retina HD display

Optional but recommended

Optional but recommended

76x76

Icon-76.png

Home screen on iPad

Required

Required

152x152

Icon-76@2x.png

Home screen on iPad with retina display

Optional but recommended

Optional but recommended

167x167

Icon-83.5@2x.png

Home screen on iPad Pro

Optional but recommended

Optional but recommended

40x40

Icon-Small-40.png

Spotlight

Optional but recommended

Optional but recommended

80x80

Icon-Small-40@2x.png

Spotlight on devices with retina display

Optional but recommended

Optional but recommended

120x120

Icon-Small-40@3x.png

Spotlight on devices with retina HD display

Optional but recommended

Optional but recommended

29x29

Icon-Small.png

Settings

Recommended if you have a Settings bundle, optional otherwise

Recommended if you have a Settings bundle, optional otherwise

58x58

Icon-Small@2x.png

Settings on devices with retina display

Recommended if you have a Settings bundle, optional otherwise

Recommended if you have a Settings bundle, optional otherwise

87x87

Icon-Small@3x.png

Settings on devices with retina HD display

Recommended if you have a Settings bundle, optional otherwise

Recommended if you have a Settings bundle, optional otherwise

It goes without saying that you don't need to include an application icon for the iPad/iPad Mini device family if your application only targets the iPhone/iPod Touch device family, and vice versa.

Step 2: Screenshots

Each application can have up to five screenshots and three previews, and you must provide at least one. If you are developing a universal application, then you need to provide separate screenshots for each device.

It is important to spend some time thinking about the screenshots. Your application's screenshots are often the only thing that a customer can use to decide whether to purchase or download your application or not. 

What a lot of developers don't know is that the screenshots don't have to be actual screenshots. The hard rule is that the size of each screenshot needs to be that of the screen size of the target device. Many companies are creative with this rule. Take a look at the screenshots of Where's My Water?, for example, which include labels highlighting key features of the app. By using this strategy, you can make screenshots much more attractive and compelling.

Step 3: Metadata

Before you submit your application, it is a good idea to have your application's metadata at hand. This includes: 

  • your application's name
  • the version number
  • the primary (and an optional secondary) category
  • a concise description
  • keywords
  • a support URL

If you are submitting an update, then you can also provide information for the What's New in this Version section.

Does your application require users to sign in? Then you also need to provide Apple with a test or demo account to make sure that the review team can immediately sign in and use your application without first having to sign up for an account.


4. Submission Preparation

The submission process has become much easier these days. You can now validate and submit an application using Xcode, for example. First, however, you need to create your application in iTunes Connect.

Visit iTunes Connect, sign in with your iOS developer account, and click Manage Your Apps on the right. Click the Add New App in the top left, select iOS App, and fill out the form.

Step 1: Basic Information

The App Name, which needs to be unique, is the name of your application as it will appear in the App Store. This can be different than the name that is displayed below your application icon on the home screen, but it is recommended to choose the same name. 

The SKU Number is a unique string that identifies your application. I usually use the application's bundle identifier. 

The last piece of information is the Bundle ID of your application. This means selecting the (wildcard or explicit) App ID that you created earlier from the drop-down menu.

Specifying Name SKU Number and Bundle ID

Step 2: Price and Availability

In the next step, you specify your application's price and availability. Apple works with price tiers so that you don't have to specify a price for each country that Apple operates in. You can also specify in which stores your application should—or shouldn't—be available. 

The information that you enter in this step can be modified once your application is live in the App Store. In other words, you can change the price and availability of an application without having to submit an update. You can easily do this by selecting the Pricing and Availability tab on the left of your app's iTunes Connect page.

Specifying Price and Availability

Step 3: Metadata

We've already covered the application's metadata. The only aspect that I haven't talked about yet is your application's rating. Based on your application's content and functionality, it is given a rating. This rating is not only useful for telling users about your application's content and features, but is also used by the operating system for the parental controls features.

It is strongly recommended that you don't try to outsmart the rating system. Apple is well aware of this strategy and will reject your application if it doesn't agree with the rating that you have set. There are many other things here that you may need to adjust based on your app, but we won't go over them since they are pretty self-explanatory. To do this, go to the App Information tab in the left pane.


Entering Your Applications Metadata and Assigning a Rating

5. Uploading the App Binary

To submit your app, you need to create an archive. You can only create an archive by building your application on a generic device. If you select the iOS Simulator in the active scheme, you will notice that the Archive option in Xcode's Product menu is grayed out. Connect an iOS device to your Mac, select it in the active scheme, and select Archive from Xcode's Product menu.

Uploading the App Binary

If all went well, you should now have an archive, and Xcode's Organizer should automatically open and show you the archive you just created. 

Select the archive from the list and click the Upload to App Store... button on the right. The application binary is then uploaded to Apple's servers. 

During this process, your application is also validated. If an error occurs during the validation, the submission process will fail. The validation process is very useful as it will tell you if there is something wrong with your application binary that would otherwise result in a rejection by the App Store review team.

Submit Your Application to the iOS App Store
Preparing the Archive
An Error is Shown if Validation Fails

6. Waiting

If the submission process went without problems, your application's status will change to Waiting for Review. It takes several days for Apple to review your app, and the time it takes tends to fluctuate over time.

Good luck!

Conclusion

The submission process is quite lengthy for a new application, but submitting an update to the App Store is much less cumbersome. Keep in mind that the submission process is much more involved if your application is localized in various languages as your application's metadata needs to be localized as well. However, localizing your application is well worth the effort as it often results in higher sales and positive customer feedback.

If you want to learn more about Swift and iOS development, check out some of our in-depth courses here at Envato Tuts+.

2017-09-07T17:55:43.880Z2017-09-07T17:55:43.880ZBart Jacobs

How to Submit an iOS App to the App Store

$
0
0
tag:code.tutsplus.com,2005:PostPresenter/mobile-16812

You have worked weeks or months on your first iOS application, and you are ready to submit your masterpiece to Apple's App Store. How do you do this? Is your application ready for submission? I am sure that some of these questions have entered your mind at one point or another. 

Is submitting an application as simple as sending Apple your application's binary? Not quite. With this tutorial, I will provide you with a detailed map to get your application submitted to Apple's App Store.

Introduction

Even though the App Store review process is a black box for the most part, that doesn't mean that you can't prepare yourself and your application for Apple's review process. Apple provides guidelines to help you stay within the sometimes invisible boundaries of what is and isn't allowed in the App Store.

The first time you submit an application to the App Store is exciting and nerve-racking at the same time. Even for experienced iOS developers, submitting an application to the App Store is often a stressful undertaking because it is something that most developers don't do on a daily basis.

Throughout this article, I am assuming that you are a registered iOS developer, which means that you are enrolled in Apple's iOS Developer Program and are allowed to submit applications for publication in the App Store. To submit an iOS application to the App Store, you need to be a registered iOS developer. Red flag? Don't worry. You can enroll in Apple's iOS Developer Program by visiting the Apple Developer page and clicking the Enroll button. 

Enrolling in Apples iOS Developer Program

1. Is Your Application Ready?

Step 1: Testing

An application isn't necessarily ready when you've written the last line of code or implemented the final feature of the application's specification. 

Have you tested your application on one or more physical devices? Have you profiled your application for memory leaks and performance issues? Does your application crash from time to time? 

The family of iOS devices has grown substantially over the years, and it is important to test your application on as many iOS devices as you can lay your hands on. Common issues include not optimizing an application for certain screen sizes. The iOS Simulator is a great tool, but it runs on your Mac, which has more memory and processing power than the phone in your pocket. 

Apple's Review Process isn't airtight, but it is very capable of identifying problems that might affect your application's user experience. If your application crashes from time to time or it becomes slow after ten minutes of use, then you have some work to do before submitting it to the App Store. 

Even if Apple's review team doesn't spot the problem, your users will. If the people using your application are not pleased, they will leave bad reviews on the App Store, which may harm sales or inhibit downloads.

Step 2: Rules and Guidelines

As I mentioned earlier, Apple provides developers with a number of documents that are a great help during the creation and development process of your application. 

The documents that you should be aware of are the iOS Human Interface Guidelines and the App Store Review Guidelines. Despite the availability of these documents, it seems that few developers take the time to browse them, let alone read them. It shouldn't be a surprise that some applications are therefore rejected even though the reason for the rejection is clearly stated in these documents.

Even if you don't intend to read the iOS Human Interface Guidelines or the App Store Review Guidelines, it is important to know some of the rules that they talk about. Take a look at the short list below to get an idea of what your application should and shouldn't do.

Your application:

  • shouldn't crash
  • shouldn't use private APIs
  • shouldn't replicate the functionality of native applications
  • should use In App Purchase for in-app (financial) transactions
  • shouldn't use the camera or microphone without the user's knowledge
  • should only use artwork that is your copyright or that you have permission to use

Keep in mind that this is a tiny subset of the guidelines included in the aforementioned documents. The majority of the rules and guidelines are trivial, but some are not, and you might even violate some of them inadvertently. 

Let me give you an example. Before Apple started using its own maps (a really long time ago), the MapKit framework used Google's maps. This was clear to the user because of the small Google logo in the bottom left corner of each map. However, if some part of your application's user interface covered or obscured Google's logo, your application would get rejected. This rule seems trivial, but it is a rule that is easily violated if you're not careful. Even automated tests won't cover you in this case.


2. Prerequisites

Before you can even start thinking about submitting your application to the App Store, you need to make sure that you have an App ID, a valid distribution certificate, and a valid provisioning profile. Let me show you what this entails.

Step 1: App ID

Every application needs an App ID or application identifier. There are two types of application identifiers: an explicit App ID and a wildcard App ID. A wildcard App ID can be used for building and installing multiple applications. Despite the convenience of a wildcard App ID, an explicit App ID is required if your application uses iCloud or makes use of other iOS features, such as Game Center, Apple Push Notifications, or In App Purchase.

If you're not sure what App ID best fits your project, then I recommend reading Technical Note QA1713 for more information about the topic.

Step 2: Distribution Certificate

To submit an application to the App Store, you need to create an iOS provisioning profile for distribution. To create such a provisioning profile, you first need to create a distribution certificate. The process for creating a distribution certificate is very similar to creating a development certificate. If you have tested your application on a physical device, then you are probably already familiar with the creation of a development certificate.

If you need to refresh your memory, I suggest reading Apple's guide, Code Signing your Apps, about signing certificates and provisioning profiles. The process is not difficult once you understand how the various pieces of the puzzle fit together.

Step 3: Provisioning Profile

Once you've created an App ID and a distribution certificate, you can create an iOS provisioning profile for distributing your application through the App Store. 

Keep in mind that you cannot use the same provisioning profile that you use for ad hoc distribution. You need to create a separate provisioning profile for App Store distribution. If you use a wildcard App ID for your project, then you can use the same provisioning profile for multiple applications.

Step 4: Build Settings

With the App ID, distribution certificate, and provisioning profile in place, it is time to configure your target's build settings in Xcode. This means selecting the target from the list of targets in Xcode's Project Navigator, opening the Build Settings tab at the top, and updating the settings in the Signing section. You will need to set the Code Signing to Automatic. 

Configuring the Targets Build Settings

Even though the code signing process is fairly simple once you understand it, it is something that trips up a lot of developers. I don't know a single Cocoa developer who hasn't run into code signing issues at some point in their career. Once you've cleared this hurdle, the rest of the submission process is fairly easy.

Step 5: Deployment Target

It is useful to think a little about your application's deployment target. Each target in an Xcode project has a deployment target, which indicates the minimum version of the operating system that the application can run on. 

It is up to you to set the deployment target, but keep in mind that modifying the deployment target is not something you can do without consequences once your application is in the App Store. If you increase the deployment target for an update of your application, then users who have already purchased your application but don't meet the new deployment target cannot run the update. 

It gets really problematic when a user downloads an update through iTunes (not the device), replacing the previous version on their computer, and then discovers that the new update doesn't run on their device.

I have two very simple tips with regards to your application's deployment target:

  1. Be very careful when you decide to increase the deployment target of an existing application. Mention this in the application's release notes of the updates that precede the change, and again in the update that uses the new deployment target. If you warn your customers well in advance, you have done all you can to prevent potential problems. 
  2. For new applications, I almost always set the deployment target to the last major release.

3. Assets

Step 1: Icons

You probably know that an application icon is a vital component of every iOS application, but you need to make sure that your application ships with the correct sizes of the artwork. Take a look at the table below: 

Image Size (px)

File Name

Used For

App Store

Ad Hoc

512x512

iTunesArtwork

App list in iTunes

Do not include

Optional but recommended

1024x1024

iTunesArtwork@2x

App list in iTunes for devices with retina display

Do not include

Optional but recommended

120x120

Icon-60@2x.png

Home screen on iPhone/iPod Touch with retina display

Required

Required

180x180

Icon-60@3x.png

Home screen on iPhone with retina HD display

Optional but recommended

Optional but recommended

76x76

Icon-76.png

Home screen on iPad

Required

Required

152x152

Icon-76@2x.png

Home screen on iPad with retina display

Optional but recommended

Optional but recommended

167x167

Icon-83.5@2x.png

Home screen on iPad Pro

Optional but recommended

Optional but recommended

40x40

Icon-Small-40.png

Spotlight

Optional but recommended

Optional but recommended

80x80

Icon-Small-40@2x.png

Spotlight on devices with retina display

Optional but recommended

Optional but recommended

120x120

Icon-Small-40@3x.png

Spotlight on devices with retina HD display

Optional but recommended

Optional but recommended

29x29

Icon-Small.png

Settings

Recommended if you have a Settings bundle, optional otherwise

Recommended if you have a Settings bundle, optional otherwise

58x58

Icon-Small@2x.png

Settings on devices with retina display

Recommended if you have a Settings bundle, optional otherwise

Recommended if you have a Settings bundle, optional otherwise

87x87

Icon-Small@3x.png

Settings on devices with retina HD display

Recommended if you have a Settings bundle, optional otherwise

Recommended if you have a Settings bundle, optional otherwise

It goes without saying that you don't need to include an application icon for the iPad/iPad Mini device family if your application only targets the iPhone/iPod Touch device family, and vice versa.

Step 2: Screenshots

Each application can have up to five screenshots and three previews, and you must provide at least one. If you are developing a universal application, then you need to provide separate screenshots for each device.

It is important to spend some time thinking about the screenshots. Your application's screenshots are often the only thing that a customer can use to decide whether to purchase or download your application or not. 

What a lot of developers don't know is that the screenshots don't have to be actual screenshots. The hard rule is that the size of each screenshot needs to be that of the screen size of the target device. Many companies are creative with this rule. Take a look at the screenshots of Where's My Water?, for example, which include labels highlighting key features of the app. By using this strategy, you can make screenshots much more attractive and compelling.

Step 3: Metadata

Before you submit your application, it is a good idea to have your application's metadata at hand. This includes: 

  • your application's name
  • the version number
  • the primary (and an optional secondary) category
  • a concise description
  • keywords
  • a support URL

If you are submitting an update, then you can also provide information for the What's New in this Version section.

Does your application require users to sign in? Then you also need to provide Apple with a test or demo account to make sure that the review team can immediately sign in and use your application without first having to sign up for an account.


4. Submission Preparation

The submission process has become much easier these days. You can now validate and submit an application using Xcode, for example. First, however, you need to create your application in iTunes Connect.

Visit iTunes Connect, sign in with your iOS developer account, and click Manage Your Apps on the right. Click the Add New App in the top left, select iOS App, and fill out the form.

Step 1: Basic Information

The App Name, which needs to be unique, is the name of your application as it will appear in the App Store. This can be different than the name that is displayed below your application icon on the home screen, but it is recommended to choose the same name. 

The SKU Number is a unique string that identifies your application. I usually use the application's bundle identifier. 

The last piece of information is the Bundle ID of your application. This means selecting the (wildcard or explicit) App ID that you created earlier from the drop-down menu.

Specifying Name SKU Number and Bundle ID

Step 2: Price and Availability

In the next step, you specify your application's price and availability. Apple works with price tiers so that you don't have to specify a price for each country that Apple operates in. You can also specify in which stores your application should—or shouldn't—be available. 

The information that you enter in this step can be modified once your application is live in the App Store. In other words, you can change the price and availability of an application without having to submit an update. You can easily do this by selecting the Pricing and Availability tab on the left of your app's iTunes Connect page.

Specifying Price and Availability

Step 3: Metadata

We've already covered the application's metadata. The only aspect that I haven't talked about yet is your application's rating. Based on your application's content and functionality, it is given a rating. This rating is not only useful for telling users about your application's content and features, but is also used by the operating system for the parental controls features.

It is strongly recommended that you don't try to outsmart the rating system. Apple is well aware of this strategy and will reject your application if it doesn't agree with the rating that you have set. There are many other things here that you may need to adjust based on your app, but we won't go over them since they are pretty self-explanatory. To do this, go to the App Information tab in the left pane.


Entering Your Applications Metadata and Assigning a Rating

5. Uploading the App Binary

To submit your app, you need to create an archive. You can only create an archive by building your application on a generic device. If you select the iOS Simulator in the active scheme, you will notice that the Archive option in Xcode's Product menu is grayed out. Connect an iOS device to your Mac, select it in the active scheme, and select Archive from Xcode's Product menu.

Uploading the App Binary

If all went well, you should now have an archive, and Xcode's Organizer should automatically open and show you the archive you just created. 

Select the archive from the list and click the Upload to App Store... button on the right. The application binary is then uploaded to Apple's servers. 

During this process, your application is also validated. If an error occurs during the validation, the submission process will fail. The validation process is very useful as it will tell you if there is something wrong with your application binary that would otherwise result in a rejection by the App Store review team.

Submit Your Application to the iOS App Store
Preparing the Archive
An Error is Shown if Validation Fails

6. Waiting

If the submission process went without problems, your application's status will change to Waiting for Review. It takes several days for Apple to review your app, and the time it takes tends to fluctuate over time.

Good luck!

Conclusion

The submission process is quite lengthy for a new application, but submitting an update to the App Store is much less cumbersome. Keep in mind that the submission process is much more involved if your application is localized in various languages as your application's metadata needs to be localized as well. However, localizing your application is well worth the effort as it often results in higher sales and positive customer feedback.

If you want to learn more about Swift and iOS development, check out some of our in-depth courses here at Envato Tuts+.

2017-09-07T17:55:43.880Z2017-09-07T17:55:43.880ZBart Jacobs

Put Your View Controllers on a Diet With MVVM

$
0
0

In my previous post in this series, I wrote about the Model-View-Controller pattern and some of its imperfections. Despite the clear benefits MVC brings to software development, it tends to fall short in large or complex Cocoa applications.

This isn't news, though. Several architectural patterns have emerged over the years, aiming to address the shortcomings of the Model-View-Controller pattern. You may have heard of MVP, Model-View-Presenter, and MVVM, Model-View-ViewModel, for example. These patterns look and feel similar to the Model-View-Controller pattern, but they also tackle some of the issues the Model-View-Controller pattern suffers from.

1. Why Model-View-ViewModel

I had been using the Model-View-Controller pattern for years before I accidentally stumbled upon the Model-View-ViewModel pattern. It's not surprising that MVVM is a latecomer to the Cocoa community, since its origins lead back to Microsoft. However, the MVVM pattern has been ported to Cocoa and adapted to the requirements and needs of the Cocoa frameworks and has recently been gaining traction in the Cocoa community.

Most appealing is how MVVM feels like an improved version of the Model-View-Controller pattern. This means that it doesn't require a dramatic change of mindset. In fact, once you understand the fundamentals of the pattern, it's fairly easy to implement, no more difficult than implementing the Model-View-Controller pattern.

2. Putting View Controllers on a Diet

In the previous post, I wrote that the controllers in a typical Cocoa application are a bit different from the controllers Reenskaug defined in the original MVC pattern. On iOS, for example, a view controller controls a view. Its sole responsibility is populating the view it manages and responding to user interaction. But that's not the only responsibility of view controllers in most iOS applications, is it?

The MVVM pattern introduces a fourth component to the mix, the view model, which helps refocus the view controller. It does this by taking over some of the responsibilities of the view controller. Take a look at the diagram below to better understand how the view model fits into the Model-View-ViewModel pattern.

The MVVM Pattern

As the diagram illustrates, the view controller no longer owns the model. It's the view model that owns the model, and the view controller asks the view model for the data it needs to display.

This is an important difference from the Model-View-Controller pattern. The view controller has no direct access to the model. The view model hands the view controller the data it needs to display in its view.

The relationship between the view controller and its view remains unchanged. That's important because it means that the view controller can focus exclusively on populating its view and handling user interaction. That's what the view controller was designed for.

The result is pretty dramatic. The view controller is put on a diet, and many responsibilities are shifted to the view model. You no longer end up with a view controller that spans hundreds or even thousands of lines of code.

3. Responsibilities of the View Model

You're probably wondering how the view model fits into the bigger picture. What are the tasks of the view model? How does it relate to the view controller? And what about the model?

The diagram I showed you earlier gives us a few hints. Let's start with the model. The model is no longer owned by the view controller. The view model owns the model, and it acts as a proxy to the view controller. Whenever the view controller needs a piece of data from its view model, the latter asks its model for the raw data and formats it in such a way that the view controller can immediately use it in its view. The view controller isn't responsible for data manipulation and formatting.

The diagram also reveals that the model is owned by the view model, not the view controller. It's also worth pointing out that the Model-View-ViewModel pattern respects the close relationship of the view controller and its view, which is characteristic for Cocoa applications. That's why MVVM feels like a natural fit for Cocoa applications.

4. An Example

Because the Model-View-ViewModel pattern is not native to Cocoa, there are no strict rules to implement the pattern. Unfortunately, this is something many developers get confused by. To clarify a few things, I'd like to show you a basic example of an application that uses the MVVM pattern. We create a very simple application that fetches weather data for a predefined location from the Dark Sky API and displays the current temperature to the user.

Step 1: Set Up the Project

Fire up Xcode and create a new project based on the Single View Application template. I'm using Xcode 8 and Swift 3 for this tutorial.

Setting Up the Project

Name the project MVVM, and set Language to Swift and Devices to iPhone.

Configuring the Project

Step 2: Create a View Model

In a typical Cocoa application powered by the Model-View-Controller pattern, the view controller would be in charge of performing the network request. You could use a manager for performing the network request, but the view controller would still know about the origins of the weather data. More importantly, it would receive the raw data and would need to format it before displaying it to the user. This isn't the approach we take when adopting the Model-View-ViewModel pattern.

Let's create a view model. Create a new Swift file, name it WeatherViewViewModel.swift, and define a class named WeatherViewViewModel.

Creating a View Model

The idea is simple. The view controller asks the view model for the current temperature for a predefined location. Because the view model sends a network request to the Dark Sky API, the method accepts a closure, which is invoked when the view model has data for the view controller. That data could be the current temperature, but it could also be an error message. This is what the currentTemperature(completion:) method of the view model looks like. We'll fill in the details in a few moments.

We declare a type alias for convenience and define a method, currentTemperature(completion:), that accepts a closure of type CurrentTemperatureCompletion

The implementation isn't hard if you're familiar with networking and the URLSession API. Take a look at the code below and notice that I've used an enum, API, to keep everything nice and tidy.

The only piece of code that I haven't showed you yet is the implementation of the temperature(from:) method. In this method, we extract the current temperature from the Dark Sky response.

In a production application, I'd opt for a more robust solution to parse the response, such as ObjectMapper or Unbox.

Step 3: Integrate the View Model

We can now use the view model in the view controller. We create a property for the view model, and we also define three outlets for the user interface.

Notice that the view controller owns the view model. In this example, the view controller is also responsible for instantiating its view model. In general, I prefer to inject the view model into the view controller, but let's keep it simple for now.

In the view controller's viewDidLoad() method, we invoke a helper method, fetchWeatherData().

In fetchWeatherData(), we ask the view model for the current temperature. Before we request the temperature, we'll hide the label and button and show the activity indicator view. In the closure we pass to fetchWeatherData(completion:), we update the user interface by populating the temperature label and hiding the activity indicator view.

The button is wired to an action, fetchWeatherData(_:), in which we also invoke the fetchWeatherData() helper method. As you can see, the helper method helps us avoid code duplication.

Step 4: Create the User Interface

The last piece of the puzzle is to create the user interface of the example application. Open Main.storyboard and add a label and a button to a vertical stack view. We'll also add an activity indicator view on top of the stack view, centered vertically and horizontally.

Creating the User Interface

Don't forget to wire up the outlets and the action we defined in the ViewController class!

Now build and run the application to give it a try. Remember that you need a Dark Sky API key to make the application work. You can sign up for a free account on the Dark Sky website.

5. What Are the Benefits?

Even though we only moved a few bits and pieces to the view model, you may be wondering why this is necessary. What did we gain? Why would you add this additional layer of complexity?

The most obvious gain is that the view controller is leaner and more focused on managing its view. That's the core task of a view controller: managing its view.

But there's a more subtle benefit. Because the view controller isn't responsible for fetching the weather data from the Dark Sky API, it isn't aware of the details related to this task. The weather data could come from a different weather service or from a cached response. The view controller wouldn't know, and it doesn't need to know.

Testing also improves dramatically. View controllers are known to be hard to test because of their close relationship to the view layer. By moving some of the business logic to the view model, we instantly improve the testability of the project. Testing view models is surprisingly easy because they don't have a link to the application's view layer.

Conclusion

The Model-View-ViewModel pattern is a significant step forward in designing Cocoa applications. View controllers aren't so massive, view models are easier to compose and test, and your project becomes more manageable as a result.

In this short series, we only scratched the surface. There's a lot more to write about the Model-View-ViewModel pattern. It's become one of my favorite patterns over the years, and that's why I keep speaking and writing about it. Give it a try and let me know what you think!

In the meantime, check out some of our other posts about Swift and iOS app development.

2017-09-08T13:00:00.000Z2017-09-08T13:00:00.000ZBart Jacobs
Viewing all 1836 articles
Browse latest View live