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

Swift From Scratch: Closures

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

If you've worked with blocks in C or Objective-C or lambdas in Ruby, then you won't have a hard time wrapping your head around the concept of closures. Closures are nothing more than blocks of functionality that you can pass around in your code.

As a matter of fact, we've already worked with closures in the previous lessons. That's right: functions are closures too. Let us start with the basics and inspect the anatomy of a closure.

1. What Is a Closure?

As I said, a closure is a block of functionality that you can pass around in your code. You can pass a closure as an argument of a function or you can store it as a property of an object. Closures have many use cases.

The name closure hints at one of the key characteristics of closures. A closure captures the variables and constants of the context in which it is defined. This is sometimes referred to as closing over those variables and constants. We're going to look at value capturing in more detail at the end of this lesson.

Flexibility

You've already learned that functions can be incredibly powerful and flexible. Because functions are closures, closures are just as flexible. In this article, you discover just how flexible and powerful they are.

Memory Management

The C programming language has a similar concept, blocks. Closures in Swift, however, have a few benefits. One of the key advantages of closures in Swift is that memory management is something you, the developer, don't have to worry about.

Even retain cycles, which aren't uncommon in C or Objective-C, are handled by Swift. This reduces hard-to-find memory leaks or crashes that are caused by invalid pointers.

2. Syntax

The basic syntax of a closure isn't difficult, and it may remind you of global and nested functions, which we covered earlier in this series. Take a look at the following example.

The first thing you notice is that the entire closure is wrapped in a pair of curly braces. The parameters of the closure are wrapped in a pair of parentheses, separated from the return type by the -> symbol. The above closure accepts one argument, a, of type Int, and returns an Int. The body of the closure starts after the in keyword.

Named closures, that is global and nested functions, look a bit different. The following example should illustrate the differences.

The most prominent differences are the use of the func keyword and the position of the parameters and return type. A closure starts and ends with a curly brace, wrapping the parameters, return type, and closure body. Despite these differences, remember that every function is a closure. Not every closure is a function, though.

3. Closures as Parameters

Closures are powerful, and the following example illustrates how useful they can be. In the example, we create an array of states. We invoke the map(_:) function on the array to create a new array that only contains the first two letters of each state as a capitalized string.

The map(_:) function or method is common to many programming languages and libraries, such as Ruby, PHP, and JavaScript. In the above example, the map(_:) function is invoked on the states array, transforms its contents, and returns a new array that contains the transformed values. Don't worry about the body of the closure for now.

Type Inference

Previously in this series, we learned that Swift is quite smart. Let me show you exactly how smart. The array of states is an array of strings. Because we invoke the map(_:) function on the array, Swift knows that the state argument is of type String. This means that we can omit the type, as shown in the updated example below.

There are a few more things we can omit from the above example, resulting in the following one-liner.

Let me explain what's happening. 

The compiler can infer that we return a string from the closure that we pass to the map(_:) function, which means there's no reason to include it in the closure expression definition. 

We can only do this if the closure's body includes a single statement, though. In that case, we can put that statement on the same line as the closure's definition, as shown in the above example. Because there's no return type in the definition and no -> symbol preceding the return type, we can omit the parentheses enclosing the closure's parameters.

Shorthand Argument Names

It doesn't stop here, though. We can make use of shorthand argument names to simplify the above closure expression even more. When using an inline closure expression, as in the above example, we can omit the list of parameters, including the in keyword that separates the parameters from the closure body.

In the closure body, we reference the arguments using shorthand argument names that Swift provides us with. The first argument is referenced by $0, the second by $1, etc.

In the updated example below, I have omitted the list of parameters and the in keyword, and replaced the state argument in the closure's body with the shorthand argument name $0. The resulting statement is more concise without compromising readability.

Trailing Closures

The Swift programming language also defines a concept known as trailing closures. The idea is simple. If you pass a closure as the last argument of a function, you can place that closure outside the parentheses of the function call. The following example demonstrates how this works.

If the only argument of the function call is the closure, then it's even possible to omit the parentheses of the function call.

Note that this also works for closures that contain multiple statements. In fact, that is the main reason trailing closures are available in Swift. If a closure is long or complex and it's the last argument of a function, it is often better to use the trailing closure syntax.

4. Capturing Values

When using closures, you'll often find yourself using or manipulating constants and variables from the closure's surrounding context in the body of the closure. This is often referred to as value capturing. It simply means that a closure can capture the values of constants and variables from the context in which it is defined. Take the following example to better understand the concept of value capturing.

I'm sure you agree the above example is a bit contrived, but it clearly shows how value capturing works in Swift. The nested functions, changeToUppercase() and changeToLowercase(), have access to the outer function's arguments, states, as well as the newStates variable declared in the outer function. 

Let me explain what happens.

The changeCase(uppercase:ofStrings:) function accepts a boolean as its first argument and a variadic parameter of type String as its second parameter. The function returns an array of strings composed of the strings passed to the function as the second argument. In the function's body, we create a mutable array of strings, newStrings, in which we store the modified strings.

The nested functions loop over the strings that are passed to the changeCase(uppercase:ofStrings:) function and change the case of each string. As you can see, they have direct access to the strings passed to the changeCase(uppercase:ofStrings:) function as well as the newStrings array, which is declared in the body of the changeCase(uppercase:ofStrings:) function.

We check the value of uppercase, call the appropriate function, and return the newStrings array. The two lines at the end of the example demonstrate how the changeCase(uppercase:ofStrings:) function works.

Even though I've demonstrated value capturing with functions, remember that every function is a closure. In other words, the same rules apply to unnamed closures.

Closures

It's been mentioned several times in this article: functions are closures. There are three kinds of closures:

  • global functions
  • nested functions
  • closure expressions

Global functions, such as the print(_:separator:terminator:) function of the Swift standard library, capture no values. Nested functions, however, have access to and can capture the values of constants and values of the function they are defined in. The previous example illustrates this concept.

Closure expressions, also known as unnamed closures, can capture the values of constants and variables of the context they are defined in. This is very similar to nested functions.

Copying and Referencing

A closure that captures the value of a variable is able to change the value of that variable. Swift is clever enough to know whether it should copy or reference the values of the constants and variables it captures.

Developers who learn Swift and have little experience with other programming languages will take this behavior for granted. However, it's an important advantage that Swift understands how captured values are being used in a closure and, as a result, can handle memory management for us.

Conclusion

Closures are an important concept, and you will use them often in Swift. They enable you to write flexible, dynamic code that is easy both to write and to understand. 

In the next article, we explore object-oriented programming in Swift, starting with objects, structures, and classes.

If you want to learn how to use Swift 3 to code advanced features for real-world apps, check out our course Go Further With Swift: Animation, Networking, and Custom Controls. Follow along with Markus Mühlberger as he codes a functional iOS weather app with live weather data, custom UI components, and some slick animations to bring everything to life.

 
2017-04-03T21:11:09.630Z2017-04-03T21:11:09.630ZBart Jacobs

Quick Tip: Create Autosizing Text With Android O

$
0
0

The first developer preview of Android O has arrived!

In this series of tips we’ll be exploring some of the new UI features that you can look forward to in the upcoming release of Android O(reo?).

In this first tip, we’ll be getting some hands-on experience with Android O’s new text autosizing feature, which lets you create text that contracts and expands automatically to fit the current layout.

Since this is our first look at Android O here at Envato Tuts+, let’s start by making sure our development environment is Android O-ready.

Set Up the Developer Preview

Currently, you can only access the Android O Developer Preview via the latest canary build of Android Studio.

Canary builds are the bleeding edge of Android Studio, and are typically updated on a weekly basis. While these builds are tested, they’re less stable than the official Android Studio releases, and therefore aren’t recommended for production development.

To download the latest canary build and grab the Android O preview, first launch Android Studio and select Android Studio> Preferences… from the toolbar. Select Appearance & Behavior > System Settings > Updates, and from the dropdown menu select Canary Channel.

Switch to the Android Studio Canary Channel

Then, click the accompanying Check Now button to download the latest release from the Canary Channel.

Next, restart your IDE, and open the SDK Manager. Making sure the SDK Manager’s SDK Platforms tab is selected, select the Android O Preview component.

Open the Android SDK Manager and download the O Developer Preview

Then switch to the SDK Tools tab, and select the following: 

  • Android SDK Build-Tools 26.0.0 (rc1 or higher)
  • Android SDK Platform-Tools 26.0.0 (rc1 or higher)
  • Android Emulator 26.0.0
  • Support Repository

Click the OK button to download all of these components.

Finally, create a new Android project that targets Android O. For the sake of simplicity, set the project’s minimum SDK to Android 7+ O Preview and then select Empty Activity.

Configure Your Gradle File

Once Android Studio has created your project, open its module-level build.gradle file and change the buildToolsVersion version and the Support Library version to the latest releases:

Throughout this series, we’ll be adding a number of Android O features to this sample app. If you’re going to experience these features in action, then you’ll need to create an AVD that’s running the Android O system image. Launch Android Studio’s AVD Manager, select Create Virtual Device… and then follow the onscreen instructions to create an AVD. You can use the settings of your choice, but when Android Studio prompts you to select your system image, make sure you select O.

Creating More Dynamic Text

One of the new UI features that we can look forward to in Android O is text autosizing. With the addition of a few XML attributes, you can create TextViews that automatically increase and decrease the size of your text so it always fits perfectly within the confines of the TextView. 

This automatic scaling can ensure your text remains easy to read across Android’s huge range of different screen sizes and densities. Auto-resizing can also help you avoid strange empty spaces in your layout, or text that gets cut off mid-sentence because you tried to cram too many words into a TextView.

There are two ways that you can implement text autosizing:

  • Granularity. This approach allows you to specify a minimum and maximum text size, plus a granularity value, which is how much your text can increase or decrease in size with each “step.” The TextView will then scale your text horizontally and vertically by this incremental value, until it fits the TextView perfectly.
  • Preset sizes. This is where you define an array of all the sizes your text can possibly be. Android O will then select the most appropriate size from this array, based on the TextView’s dimensions.

Whatever method you choose, you’ll always need to add the android:autoSizeText="uniform" XML attribute to your TextView, so open your layout resource file and add this element now.

Granularity

To implement autosizing using granularity, you’ll need to add the following XML attributes to your TextView:

  • autoSizeMinTextSize: The minimum size the TextView can use.
  • autoSizeMaxTextSize: The maximum size the TextView can use.
  • autoSizeStepGranularity: The increment value. This is 1px by default.

Here, I’m creating a view that can resize its text between 10sp and 100sp, in increments of 2sp:

Preset Sizes

The other option is to create an array of supported text sizes. Android O will then choose the most appropriate value from this list, based on the amount of text it has to display, the TextView’s dimensions, and the current screen configuration.  

If your project doesn’t already contain an arrays.xml file, then you can create one by right-clicking your project’s res/values directory and selecting New > Values Resource File. In the window that appears, give this file the name arrays, and then click OK.

You can then open your new res/values/arrays.xml file and define all the sizes you want your TextView to use.

Finally, reference this array using the autoSizePresetSizes attribute, for example:

Don't Forget to Test!

Once you’ve added autosizing to a TextView, boot up your Android O AVD and take a look at how your TextView renders on an emulated Android O screen. To check that autosizing is working correctly, update your TextView to display different amounts of text, and then see what impact this has on the final rendered image you see onscreen.

Testing auto-scaling text in Android O

If you do implement autosizing, then it’s important that you test your text views across a range of different screen configurations, as you may need to tweak your minimum and maximum text sizes to ensure your text remains readable across different screens.

Conclusion

In this quick tip, I showed you how to create text that scales automatically. In the next tip, we’ll be looking at how Android O is about to make it much easier to use custom fonts in your Android apps. In the meantime, check out some of our other tutorials: 

2017-04-07T12:45:06.000Z2017-04-07T12:45:06.000ZJessica Thornsby

RxJava 2 for Android Apps: RxBinding and RxLifecycle

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

RxJava is one of the most popular libraries for bringing reactive programming to the Android platform, and in this three-part series I’ve been showing you how to start using this library in your own Android projects.

In Get Started With RxJava 2 for Android, we looked at what RxJava is and what it has to offer Android developers, before creating a Hello World app that demonstrated the three core components of RxJava: an Observable, an Observer, and a subscription.

In the Reactive Programming Operators in RxJava 2 tutorial, we looked at how to perform complex data transformations using operators, and how you can combine Operators and Schedulers to finally make multithreading on Android a pain-free experience.

We also touched on RxAndroid, a library specifically designed to help you use RxJava in your Android projects, but there’s much more to explore in RxAndroid. So, in this post, I’m going to focus solely on the RxAndroid family of libraries.

Much like RxJava, RxAndroid underwent a massive overhaul in its version 2 release. The RxAndroid team decided to modularise the library, moving much of its functionality into dedicated RxAndroid add-on modules.

In this article, I’m going to show you how to set up and use some of the most popular and powerful RxAndroid modules—including a library that can make listeners, handlers and TextWatchers a thing of the past by giving you the ability to handle any Android UI event as an Observable.

And since memory leaks caused by incomplete subscriptions are the biggest drawback to using RxJava in your Android apps, I’ll also show you how to use an RxAndroid module that can handle the subscription process for you. By the end of this article, you’ll know how to use RxJava in any Activity or Fragment, without running the risk of encountering any RxJava-related memory leaks.

Creating More Reactive Android UIs

Reacting to UI events such as taps, swipes and text input is a fundamental part of developing pretty much any Android app, but handling Android UI events isn’t particularly straightforward.

You’ll typically react to UI events using a combination of listeners, handlers, TextWatchers, and possibly other components depending on the kind of UI you’re creating. Each of these components requires you to write a significant amount of boilerplate code, and to make matters worse there’s no consistency in how you implement these different components. For example, you handle OnClick events by implementing an OnClickListener:

But this is completely different to how you'd implement a TextWatcher:

This lack of consistency can potentially add a lot of complexity to your code. And if you have UI components that depend on the output of other UI components, then get ready for things to get even more complicated! Even a simple use case—such as asking the user to type their name into an EditText so you can personalise the text that appears in subsequent TextViews—requires nested callbacks, which are notoriously difficult to implement and maintain. (Some people refer to nested callbacks as “callback hell.”)

Clearly, a standardised approach to handling UI events has the potential to greatly simplify your code, and RxBinding is a library that sets out to do just that, by providing bindings that enable you to convert any Android View event into an Observable.  

Once you’ve converted a view event into an Observable, it’ll emit its UI events as streams of data that you can subscribe to in exactly the same way you’d subscribe to any other Observable.

Since we’ve already seen how you’d capture a click event using Android’s standard OnClickListener, let’s look how you’d achieve the same results using RxBinding:

Not only is this approach more concise, but it’s a standard implementation that you can apply to all the UI events that occur throughout your app. For example, capturing text input follows the same pattern as capturing click events:

An Example App With RxBinding

So you can see exactly how RxBinding can simplify your app’s UI-related code, let’s create an app that demonstrates a few of these bindings in action. I’m also going to include a View that’s dependent on the output of another View, to demonstrate how RxBinding simplifies creating relationships between UI components.

This app is going to consist of:

  • A Button that displays a Toast when tapped.
  • An EditText that detects text changes.
  • A TextView that updates to display the contents of the EditText.

Project Setup

Create an Android Studio project with the settings of your choice, and then open your module-level build.gradle file and add the latest version of the RxBinding library as a project dependency. In the interests of keeping boilerplate code to a minimum, I’m also going to be using lambdas, so I’ve updated my build.gradle file to support this Java 8 feature:

When you’re working with multiple RxJava libraries, it’s possible that you may encounter a Duplicate files copied in APK META-INF/DEPENDENCIES error message at compile time. If you do encounter this error, then the workaround is to suppress these duplicate files by adding the following to your module-level build.gradle file:

Create the Main Activity Layout

Sync your Gradle files, and then create a layout consisting of a Button, an EditText, and a TextView:

Code the Event Bindings

Now let’s look at how you’d use these RxBinding to capture the various UI events our application needs to react to. For starters, declare your imports and define the MainActivity class. 

Now you can start adding bindings to respond to UI events. The RxView.clicks method is used to bind click events. Create a binding to display a toast whenever the button is clicked:  

Next, use the RxTextView.textChanges() method to react to a text change event by updating the TextView with the contents of our EditText.

When you run your app, you'll end up with a screen like the following.

The default version of our RxBinding user interface

Install your project on a physical Android smartphone or tablet or a compatible AVD, and then spend some time interacting with the various UI elements. Your app should react to click events and text input as normal—and all without a listener, TextWatcher or callback in sight!

RxBinding user interface

RxBinding for Support Library Views

While the core RxBinding library provides bindings for all the UI elements that make up the standard Android platform, there are also RxBinding sibling modules that provide bindings for the Views that are included as part of Android’s various support libraries.

If you’ve added one or more support libraries to your project, then you’ll typically want to add the corresponding RxBinding module, too.

These sibling modules follow a straightforward naming convention that makes it easy to identify the corresponding Android support library: each sibling module simply takes the support library’s name, and replaces com.android with com.jakewharton.rxbinding2:rxbinding.

  • compile com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.0.0'
  • compile 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0'
  • compile 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.0.0'
  • compile 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0'
  • compile 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.0.0'
  • compile 'com.jakewharton.rxbinding2:rxbinding-leanback-v17:2.0.0'

If you’re using Kotlin in your Android projects, then there’s also a Kotlin version available for each RxBinding module. To access the Kotlin version, simply append -kotlin to the name of the library you want to work with, so:

Becomes:

Once you’ve converted a View event into an Observable, all of those events are emitted as a data stream. As we’ve already seen, you can subscribe to these streams and then perform whatever task you need this particular UI event to trigger, such as displaying a Toast or updating a TextView. However, you can also apply any of RxJava’s enormous collection of operators to this observable stream, and even chain multiple operators together to perform complex transformations on your UI events.

There are far too many operators to discuss in a single article (and the official docs list all the operators anyway) but when it comes to working with Android UI events, there are a few operators that can come in particularly useful.

The debounce() Operator

Firstly, if you’re worried that an impatient user might tap away at a UI element repeatedly, potentially confusing your app, then you can use the debounce() operator to filter out any UI events that are emitted in quick succession.

In the following example, I’m specifying that this button should react to an OnClick event only if there’s been at least a 500 millisecond gap since the previous click event:

The publish() Operator

You can also use the publish() operator to attach multiple listeners to the same view, something that’s traditionally been difficult to implement in Android.

The publish() operator converts a standard Observable into a connectable observable. While a regular observable starts emitting items as soon as the first observer subscribes to it, a connectable observable won’t emit anything until you explicitly instruct it to, by applying the connect() operator. This gives you a window of opportunity in which to subscribe multiple observers, without the observable starting to emit items as soon as the first subscription takes place.

Once you’ve created all your subscriptions, simply apply the connect() operator and the observable will start emitting data to all its assigned observers.  

Avoid App-Breaking Memory Leaks

As we’ve seen throughout this series, RxJava can be a powerful tool for creating more reactive, interactive Android applications, with much less code than you’d typically need to get the same results using Java alone. However, there is one major drawback to using RxJava in your Android applications—the potential for memory leaks caused by incomplete subscriptions.

These memory leaks occur when the Android system tries to destroy an Activity that contains a running Observable. Since the observable is running, its observer will still be holding a reference to the activity, and the system will be unable to garbage collect this activity as a result.

Since Android destroys and recreates Activitys each time the device’s configuration changes, your app could be creating a duplicate Activity every single time the user switches between portrait and landscape mode, as well as each time they open and close their device’s keyboard.

These Activities will hang around in the background, potentially never getting garbage collected. Since Activities are large objects, this can quickly lead to serious memory management problems, especially since Android smartphones and tablets have limited memory to begin with. The combination of a large memory leak and limited memory can quickly result in an Out Of Memory error.

RxJava memory leaks may have the potential to wreak havoc with your application’s performance, but there is an RxAndroid library that allows you to use RxJava in your app without having to worry about memory leaks.

The RxLifecycle library, developed by Trello, provides lifecycle handling APIs that you can use to limit the lifespan of an Observable to the lifecycle of an Activity or Fragment. Once this connection is made, RxLifecycle will terminate the observable’s sequence in response to lifecycle events that occur in that observable’s assigned activity or fragment. This means you can create an observable that terminates automatically whenever an activity or fragment is destroyed.

Note that we’re talking about terminating a sequence, and not unsubscribing. Although RxLifecycle is often talked about in the context of managing the subscription/unsubscription process, technically it doesn’t unsubscribe an observer. Instead, the RxLifecycle library terminates the observable sequence by emitting either the onComplete() or onError() method. When you unsubscribe, the observer stops receiving notifications from its observable, even if that observable is still emitting items. If you specifically require unsubscribe behaviour, then that is something you’ll need to implement yourself.

Using RxLifecycle

To use RxLifecycle in your Android projects, open your module-level build.gradle file and add the latest version of the RxLifeycle library, plus the RxLifecycle Android library:

Then, in the Activity or Fragment where you want to use the library’s lifecycle handling APIs, extend either RxActivity, RxAppCompatActivity or RxFragment, and add the corresponding import statement, for example:

When it comes to binding an Observable to the lifecycle of an Activity or Fragment, you can either specify the lifecycle event where the observable should terminate, or you can let the RxLifecycle library decide when it should terminate the observable sequence.

By default, RxLifecycle will terminate an observable in the complementary lifecycle event to the one where that subscription occurred, so if you subscribe to an observable during your Activity’s onCreate() method, then RxLifecycle will terminate the observable sequence during that Activity’s onDestroy() method. If you subscribe during a Fragment’s onAttach() method, then RxLifecycle will terminate this sequence in the onDetach() method.

You can leave this decision up to RxLifecycle, by using RxLifecycleAndroid.bindActivity:

Alternatively, you can specify the lifecycle event where RxLifecycle should terminate an Observable sequence, using RxLifecycle.bindUntilEvent.

Here, I’m specifying that the observable sequence should be terminated in onDestroy():

Working With Android Marshmallow Permissions

The final library we’re going to look at is RxPermissions, which was designed to help you use RxJava with the new permissions model introduced in Android 6.0. This library also allows you to issue a permission request and handle the permission result in the same location, instead of requesting the permission in one place and then handling its results separately, in Activity.onRequestPermissionsResult().

Start by adding the RxPermissions library to your build.gradle file:

Then, create an RxPermissions instance:

You’re then ready to start making permission requests via the RxPermissions library, using the following formula:

Where you issue your permissions request is crucial, as there’s always a chance that the hosting Activity may be destroyed and then recreated while the permissions dialogue is onscreen, usually due to a configuration change such as the user moving between portrait and landscape modes. If this occurs, then your subscription may not be recreated, which means you won’t be subscribed to the RxPermissions observable and won’t receive the user’s response to the permission request dialog. To guarantee that your application receives the user’s response, always invoke your request during an initialisation phase such as Activity.onCreate()Activity.onResume(), or View.onFinishInflate().

It’s not uncommon for features to require several permissions. For example, sending an SMS message usually requires your app to have the SEND_SMS and READ_CONTACTS permissions. The RxPermissions library provides a concise method of issuing multiple permissions requests, and then combining the user’s responses into a single false (one or more permissions was denied) or true (all permissions were granted) response that you can then react to accordingly.

You’ll typically want to trigger a permission request in response to a UI event, such as the user tapping a menu item or button, so RxPermissions and RxBiding are two libraries that work particularly well together.

Handling the UI event as an observable and making the permission request via RxPermissions allows you to perform a lot of work with just a few lines of code:

Conclusion

After reading this article, you have some ideas of how to cut a lot of boilerplate code from your Android apps—using RxJava to handle all of your application’s UI events, and issuing your permission requests via RxPermissions. We also looked at how you can use RxJava in any Android Activity or Fragment, without having to worry about the memory leaks that can be caused by incomplete subscriptions.

We’ve explored some of the most popular and useful RxJava and RxAndroid libraries in this series, but if you’re eager to see what else RxJava has to offer Android developers, check out some of the many other RxAndroid libraries. You’ll find a comprehensive list of additional RxAndroid libraries over at GitHub.

In the meantime, check out some of our other Android development posts here on Envato Tuts+!

2017-04-05T11:22:51.000Z2017-04-05T11:22:51.000ZJessica Thornsby

Quick Tip: Create Autosizing Text With Android O

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

The first developer preview of Android O has arrived!

In this series of tips we’ll be exploring some of the new UI features that you can look forward to in the upcoming release of Android O(reo?).

In this first tip, we’ll be getting some hands-on experience with Android O’s new text autosizing feature, which lets you create text that contracts and expands automatically to fit the current layout.

Since this is our first look at Android O here at Envato Tuts+, let’s start by making sure our development environment is Android O-ready.

Set Up the Developer Preview

Currently, you can only access the Android O Developer Preview via the latest canary build of Android Studio.

Canary builds are the bleeding edge of Android Studio, and are typically updated on a weekly basis. While these builds are tested, they’re less stable than the official Android Studio releases, and therefore aren’t recommended for production development.

To download the latest canary build and grab the Android O preview, first launch Android Studio and select Android Studio> Preferences… from the toolbar. Select Appearance & Behavior > System Settings > Updates, and from the dropdown menu select Canary Channel.

Switch to the Android Studio Canary Channel

Then, click the accompanying Check Now button to download the latest release from the Canary Channel.

Next, restart your IDE, and open the SDK Manager. Making sure the SDK Manager’s SDK Platforms tab is selected, select the Android O Preview component.

Open the Android SDK Manager and download the O Developer Preview

Then switch to the SDK Tools tab, and select the following: 

  • Android SDK Build-Tools 26.0.0 (rc1 or higher)
  • Android SDK Platform-Tools 26.0.0 (rc1 or higher)
  • Android Emulator 26.0.0
  • Support Repository

Click the OK button to download all of these components.

Finally, create a new Android project that targets Android O. For the sake of simplicity, set the project’s minimum SDK to Android 7+ O Preview and then select Empty Activity.

Configure Your Gradle File

Once Android Studio has created your project, open its module-level build.gradle file and change the buildToolsVersion version and the Support Library version to the latest releases:

Throughout this series, we’ll be adding a number of Android O features to this sample app. If you’re going to experience these features in action, then you’ll need to create an AVD that’s running the Android O system image. Launch Android Studio’s AVD Manager, select Create Virtual Device… and then follow the onscreen instructions to create an AVD. You can use the settings of your choice, but when Android Studio prompts you to select your system image, make sure you select O.

Creating More Dynamic Text

One of the new UI features that we can look forward to in Android O is text autosizing. With the addition of a few XML attributes, you can create TextViews that automatically increase and decrease the size of your text so it always fits perfectly within the confines of the TextView. 

This automatic scaling can ensure your text remains easy to read across Android’s huge range of different screen sizes and densities. Auto-resizing can also help you avoid strange empty spaces in your layout, or text that gets cut off mid-sentence because you tried to cram too many words into a TextView.

There are two ways that you can implement text autosizing:

  • Granularity. This approach allows you to specify a minimum and maximum text size, plus a granularity value, which is how much your text can increase or decrease in size with each “step.” The TextView will then scale your text horizontally and vertically by this incremental value, until it fits the TextView perfectly.
  • Preset sizes. This is where you define an array of all the sizes your text can possibly be. Android O will then select the most appropriate size from this array, based on the TextView’s dimensions.

Whatever method you choose, you’ll always need to add the android:autoSizeText="uniform" XML attribute to your TextView, so open your layout resource file and add this element now.

Granularity

To implement autosizing using granularity, you’ll need to add the following XML attributes to your TextView:

  • autoSizeMinTextSize: The minimum size the TextView can use.
  • autoSizeMaxTextSize: The maximum size the TextView can use.
  • autoSizeStepGranularity: The increment value. This is 1px by default.

Here, I’m creating a view that can resize its text between 10sp and 100sp, in increments of 2sp:

Preset Sizes

The other option is to create an array of supported text sizes. Android O will then choose the most appropriate value from this list, based on the amount of text it has to display, the TextView’s dimensions, and the current screen configuration.  

If your project doesn’t already contain an arrays.xml file, then you can create one by right-clicking your project’s res/values directory and selecting New > Values Resource File. In the window that appears, give this file the name arrays, and then click OK.

You can then open your new res/values/arrays.xml file and define all the sizes you want your TextView to use.

Finally, reference this array using the autoSizePresetSizes attribute, for example:

Don't Forget to Test!

Once you’ve added autosizing to a TextView, boot up your Android O AVD and take a look at how your TextView renders on an emulated Android O screen. To check that autosizing is working correctly, update your TextView to display different amounts of text, and then see what impact this has on the final rendered image you see onscreen.

Testing auto-scaling text in Android O

If you do implement autosizing, then it’s important that you test your text views across a range of different screen configurations, as you may need to tweak your minimum and maximum text sizes to ensure your text remains readable across different screens.

Conclusion

In this quick tip, I showed you how to create text that scales automatically. In the next tip, we’ll be looking at how Android O is about to make it much easier to use custom fonts in your Android apps. In the meantime, check out some of our other tutorials: 

2017-04-07T12:45:06.000Z2017-04-07T12:45:06.000ZJessica Thornsby

Serverless Apps With Firebase Cloud Functions

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

Firebase's goal is to help developers build better apps and grow them into successful businesses. By taking care of your app back-end or infrastructure, Firebase lets you focus on solving problems for your users. One of the new exciting features announced at the Google Cloud Next '17 Conference this March for Firebase was Cloud Functions. In this tutorial, you'll learn about this new feature by building a simple Android app with it. 

What Are Cloud Functions for Firebase?

Firebase Cloud Functions run in a hosted, private, and scalable Node.js environment where you can run JavaScript code. You simply create reactive functions that trigger whenever an event occurs. Cloud functions are available for both Google Cloud Platform and Firebase (they were built on top of Google Cloud Functions). 

For now, Cloud Functions support the following triggers that you can listen to and respond to:

So Why Use Cloud Functions?

So now you have seen the range of capabilities that Cloud Functions can offer. But why use them? 

Running and setting up a back end and servers can be a real pain—you have to handle issues such as scalability and writing code in server-side languages—but with Cloud Functions, this complexity is reduced. Also, computationally intensive tasks can be performed in the cloud instead of on the client device (such as image resizing for upload or writing to multiple paths of your database). Your code will also be more secure in the cloud than on the client device, so you can securely store data such as secret keys on your server. 

In this tutorial, you'll learn how to use the Realtime Database Triggers that will fire when a database write event occurs. Then, we'll see how to use the Firebase Cloud Messaging service to send a notification to devices that subscribed to a topic. We'll create a simple app called Tutsplus Alerts, which will send a notification to subscribers of the "android" topic whenever a new article is available.

Prerequisites 

To follow along with this tutorial, you should be familiar with:

And you should have Node.js installed on your computer.

Check out the following tutorials here on Envato Tuts+ if you need some help getting started with Firebase:

1. Create a Firebase Cloud Function

Install the Firebase CLI 

Now that the prerequisites are set up, let's download Cloud Functions.

To begin to use Cloud Functions, we need the Firebase CLI (command-line interface) installed from npm. If you already have Node set up on your machine, you can install Cloud Functions with:

This command will install the Firebase CLI globally along with any necessary Node.js dependencies.

Initialize the Project

To initialize your project:

  1. Run firebase login to log in to Firebase via the browser and authenticate the CLI tool.
  2. Create a new project directory with the name tutsplus-alerts.
  3. Finally, run firebase init functions from that new directory. This tool gives you an option to install dependencies with NPM. It is safe to decline if you want to manage dependencies in another way.

After these commands complete successfully, your project structure looks like this:

  • .firebaserc: a hidden file that helps you quickly switch between projects with firebase use.
  • firebase.json: describes properties for your project.
  • functions/: this folder contains all the code for your functions.
  • functions/package.json: an NPM package file describing your Cloud Functions.
  • functions/index.js: the main source for your Cloud Functions code.
  • functions/node_modules/: the folder where all your NPM dependencies are installed.

Import the Needed Modules and Initialize the App 

To develop our simple Tutsplus Alerts app, we just need two node modules: Cloud Functions and Admin SDK modules (these modules are already installed for us). So go to the index.js and require these modules, and then initialize an admin app instance.

Code the Cloud Function

Now that the required modules for our project have been imported and initialized, let's code our cloud function in the index.js file. As stated earlier, we are going to write a function that will be fired when an onWrite() event occurs in our Firebase realtime database and then, in response, will send a notification (a downstream message) to device subscribers.

In the code above, we are listening to the database path /articles/{articleId}, where {articleId} represents the id of the article that was successfully written. Now, what we are really concerned about is the data that was written. To get that, we use event.data, which is a DeltaSnapshot static interface. 

Afterwards, add data from this snapshot to a message payload and send it to the "android" topic. The asynchronous code is simplified with JavaScript promises

Note that in the code above, we wrote to the console by using console.log(), which will help us in debugging and monitoring. We can view this log either in our Firebase dashboard or via the command line with: 

Be aware that since this runs on Node.js, you can install other modules available from NPM. You can also code in JavaScript ES6 or TypeScript instead of vanilla JavaScript. 

Deploy the Cloud Function

Let's deploy our Cloud Function. Run this command for deployment:

Now we can code the Android app that will subscribe to the topic, write to the realtime database, and receive a notification when data is written to our realtime database—that is when our cloud function would be executed! 

2. Create the TutsplusAlerts App

Create an Android Studio Project

First, fire up Android Studio and create a new project ''TutsplusAlerts" with an empty activity called MainActivity.

Android Studio create new project

To follow along, make sure you have integrated Firebase into your app

Add the Realtime Database Dependency

Add the following dependency to your build.gradle file:

Make sure you sync your project after adding it.

Create the Model

Let's model an article entity to be persisted to our realtime database.

Create the XML Layout 

Our XML layout for the main Activity will have just two EditTexts and just a button that will submit the new article.

Write to the Realtime Database

Now we are going to write to the Realtime Database path /articles/.

Your app will need write access to the database. For demo purposes only, you can set your Security Rules to permit all reads and writes. In a real application, you would never want to use such insecure security settings.

You can learn more about Firebase Security Rules in my post here on Envato Tuts+.

Run the App

At this stage, we can test the app and see if our Cloud Function was executed successfully. Enter a title and author, and then click the submit button. After that, visit the Functions dashboard and view the logs. Our custom log should appear.

Cloud Functions Dashboard

From the logs above, we see that we have successfully executed our Cloud Function and sent a message with a payload to devices subscribed to the 'android' topic, but no device has subscribed to the topic yet. In the next section, we'll use Firebase Cloud Messaging so that devices can subscribe to a topic and then process the incoming message from the server to show a notification. 

3. Add Firebase Cloud Messaging Support

Include the Dependency 

Include the Firebase Messaging dependency to your build.gradle file and sync your project afterwards:

Handling Messages

We need to create a service that extends FirebaseMessagingService and overrides the onMessageReceived callbacks. 

In the above code, we are also getting the data payload and showing it in a notification regardless of whether the application is in a foreground or background state.  

Update the Manifest File

Update the manifest file, including the service created earlier inside the <application> tag.

Subscribe to a Topic

Finally, we need to subscribe to the topic 'android' so that the device can receive and process messages sent to that topic. 

Run the App 

Run the app for the second time and enter a title and an author, and then click the submit button. This time, a notification will show up whenever a new article is posted to the database by any app user.

final app screenshots

To do this before Cloud Functions, you would have needed an HTTP or XMPP server, which would mean more code to write, as well as a server to set up and support.

Conclusion

In this tutorial, you learned about Cloud Functions for Firebase: what they are, why you might need them, and how to get started using Cloud Functions for your app. Be aware that Cloud Functions for Firebase is still in public beta as of this writing. 

To learn more about Cloud Functions for Firebase, do refer to the official documentation. And in the meantime, check out some of our other courses and tutorials on Android app development!

2017-04-11T16:58:26.000Z2017-04-11T16:58:26.000ZChike Mgbemena

Securing Communications on iOS

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

Mobile security has become a hot topic. For any app that communicates remotely, it is important to consider the security of user information that is sent across a network. In this post, you'll learn the current best practices for securing the communications of your iOS app in Swift. 

Use HTTPS

When developing your app, consider limiting network requests to ones that are essential. For those requests, make sure that they are made over HTTPS and not over HTTP—this will help protect your user's data from "man in the middle attacks", where another computer on the network acts as a relay for your connection, but listens in or changes the data that it passes along. The trend in the last few years is to have all connections made over HTTPS. Fortunately for us, newer versions of Xcode already enforce this.

To create a simple HTTPS request on iOS, all we need to do is append "s" to the "http" section of the URL. As long as the host supports HTTPS and has valid certificates, we will get a secure connection. This works for APIs such as URLSession, NSURLConnection, and CFNetwork, as well as popular third-party libraries such asAFNetworking.

App Transport Security

Over the years, HTTPS has had several attacks against it. Since it's important to have HTTPS configured correctly, Apple has created App Transport Security (ATS for short). ATS ensures that your app's network connections are using industry-standard protocols, so that you don't accidentally send user data insecurely. The good news is that ATS is enabled by default for apps built with current versions of Xcode.

ATS is available as of iOS 9 and OS X El Capitan. Current apps in the store will not suddenly require ATS, but apps built against newer versions of Xcode and its SDKs will have it enabled by default. Some of the best practices enforced by ATS include using TLS version 1.2 or higher, forward secrecy through ECDHE key exchange, AES-128 encryption, and the use of at least SHA-2 certificates.

It's important to note that while ATS is enabled automatically, it doesn't necessarily mean ATS is being enforced in your app. ATS works on the foundation classes such as URLSession and NSURLConnection and stream-based CFNetwork interfaces. ATS is not enforced on lower-level networking interfaces such as raw sockets, CFNetwork sockets, or any third-party libraries that would use these lower-level calls. So if you are using low-level networking, you'll have to be careful to implement ATS's best practices manually.

ATS Exceptions

Since ATS enforces the use of HTTPS and other secure protocols, you might wonder if you will still be able to make network connections that can't support HTTPS, such as when you download images from a CDN cache. Not to worry, you can control ATS settings for specific domains in your project's plist file. In Xcode, find your info.plist file, right click it, and chooseOpen As >Source Code.

You will find a section called NSAppTransportSecurity. If it is not there, you can add the code yourself; the format is as follows. 

This lets you change ATS settings for all network connections. Some of the common settings are as follows:

  • NSAllowsArbitraryLoads: Disables ATS. Don't use this! Future versions of Xcode will remove this key.
  • NSAllowsArbitraryLoadsForMedia: Allows loading of media without ATS restrictions for the AV Foundation framework. You should only allow insecure loads if your media is already encrypted by another means. (Available on iOS 10 and macOS 10.12.)
  • NSAllowsArbitraryLoadsInWebContent: Can be used to turn off the ATS restrictions from web view objects in your app. Think first before turning this off as it allows users to load arbitrary insecure content within your app. (Available on iOS 10 and macOS 10.12.)
  • NSAllowsLocalNetworking: This can be used to allow local network resources to be loaded without ATS restrictions. (Available on iOS 10 and macOS 10.12.)

The NSExceptionDomains dictionary lets you set settings for specific domains. Here is a description of some of the useful keys you can use for your domain:

  • NSExceptionAllowsInsecureHTTPLoads: Allows the specific domain to use non-HTTPS connections.
  • NSIncludesSubdomains: Specifies if the current rules are passed down to subdomains.
  • NSExceptionMinimumTLSVersion: Used to specify older, less secure TLS versions that are permitted.

Perfect Forward Secrecy

While encrypted traffic is unreadable, it may still get stored. If the private key used to encrypt that traffic is compromised in the future, the key can be used to read all the previously stored traffic. 

To prevent this kind of compromise, Perfect Forward Secrecy (PFS) generates a session keythat is unique for each communication session. If the key for a specific session is compromised, it will not compromise data from any other sessions. ATS implements PFS by default, and you can control this feature using the plist key NSExceptionRequiresForwardSecrecy. Turning this off will allow TLS ciphers that don't support perfect forward secrecy.

Certificate Transparency

Certificate Transparency is an upcoming standard designed to be able to check or audit the certificates presented during the setup of an HTTPS connection. 

When your host sets up an HTTPS certificate, it is issued by what is called a Certificate Authority (CA). Certificate Transparency aims at having close to real-time monitoring to find out if a certificate was issued maliciously or has been issued by a compromised certificate authority. 

When a certificate is issued, the certificate authority must submit the certificate to a number of append-only certificate logs, which can later be cross-checked by the client and scrutinized by the owner of the domain. The certificate must exist in at least two logs in order for the certificate to be valid.

The plist key for this feature is NSRequiresCertificateTransparency. Turning this on will enforce Certificate Transparency. This is available on iOS 10 and macOS 10.12 and later.

Certificate and Public Key Pinning

When you purchase a certificate to use HTTPS on your server, that certificate is said to be legitimate because it is signed with a certificate from an intermediate certificate authority. That certificate used by the intermediate authority might in turn be signed by another intermediate authority, and so on, as long as the last certificate is signed by a root certificate authority that is trusted. 

When an HTTPS connection is established, these certificates are presented to the client. This chain of trust is evaluated to make sure the certificates are correctly signed by a certificate authority that is already trusted by iOS. (There are ways to bypass this check and to accept your own self-signed certificate for testing, but don't do this in a production environment.) 

If any of the certificates in the chain of trust are not valid, then the entire certificate is said to be invalid and your data will not be sent out over the untrusted connection. While this is a good system, it's not foolproof. Various weaknesses exist that can make iOS trust an attacker's certificate instead of a legitimately signed certificate. 

For example, interception proxies may possess an intermediate certificate that is trusted. A reverse engineer can manually instruct iOS to accept their own certificate. Additionally, a corporation's policy may have provisioned the device to accept their own certificate. All of this leads to the ability to perform a “man in the middle” attack on your traffic, allowing it to be read. But certificate pinning will prevent connections from being established for all of these scenarios.

Certificate pinning comes to the rescue by checking the server's certificate against a copy of the expected certificate.

In order to implement pinning, the following delegate must be implemented. For URLSession, use the following:

Or for NSURLConnection, you can use:

Both methods allow you to obtain a SecTrust object fromchallenge.protectionSpace.serverTrust. Because we are overriding the authentication delegates, we must now explicitly call the function which performs the standard certificate chain checks that we've just discussed. Do this by calling the SecTrustEvaluate function. Then we can compare the server's certificate with an expected one.

Here is an example implementation.

To use this code, set the delegate of the URLSession when creating your connection.

Make sure to include the certificate in your app bundle. If your certificate is a .pem file, you will need to convert it to a .cer file in the macOS terminal:

openssl x509 -inform PEM -in mycert.pem -outform DER -out certificate.cer

Now, if the certificate is changed by an attacker, your app will detect it and refuse to make the connection.

Note that some third-party libraries such as AFNetworking support pinning already.

Sanitization and Validation

With all of the protections so far, your connections should be pretty secure against man in the middle attacks. Even so, one important rule regarding network communications is never to blindly trust the data you are receiving. In fact, it's good programming practice to design by contract. Theinputs and outputs of your methods have a contract that defines specific interface expectations; if the interface says it will return an NSNumber, then it should do so. If your server is expecting a string of 24 characters or fewer, make sure that the interface will only return up to 24 characters. 

This helps prevent innocent errors, but more importantly, it can also reduce the likelihood of various injection and memory corruption attacks. Common parsers such as the JSONSerialization class will convert text into Swift data types where these kinds of test can be done.

Other parsers may work with Objective-C equivalent objects. Here is a way to validate that an object is of the expected type in Swift.

Before you send a delegate a method, make sure the object is of the right type so that it will respond to the method—otherwise the app will crash with an “unrecognized selector” error.

Additionally, you can see if an object conforms to a protocol before trying to send messages to it:

Or you can check that it matches a Core Foundation object type.

It's a good idea to carefully choose which information from the server the user can see. For example, it's a bad idea to display an error alert that directly passes a message from the server. Error messages could disclose debugging and security-related information. One solution is to have the server send specific error codes that cause the client to show predefined messages.

Also, make sure you encode your URLs so that they only contain valid characters.NSString’s stringByAddingPercentEscapesUsingEncoding will work. It does not encode some characters such as ampersands and plus signs, but the CFURLCreateStringByAddingPercentEscapes function allows customization of what will be encoded.

Sanitizing User Data

When sending data to a server, be extremely careful when any user input is passed into commands that will be executed by an SQL server or a server that will run code. While securing a server against such attacks is beyond the scope of this article, as mobile developers we can do our part by removing characters for the language that the server is using so that the input is not susceptible to command injection attacks. Examples might be stripping quotes, semicolons, and slashes when they are not needed for the specific user input.

It is good practice to limit the length of user input. We can limit the number of characters typed in a text field by setting theUITextField's delegate and then implementing its shouldChangeCharactersInRange delegate method.

For a UITextView, the delegate method to implement this is:

User input can be further validated so that the input is of an expected format. For example, if a user is to enter an email address, we can check for a valid address:

If a user is uploading an image to the server, we can check that it is a valid image. For example, for a JPEG file, the first two bytes and last two bytes are always FF D8 and FF D9.

The list goes on, but only you as the developer will know what the expected input and output should be, given the design requirements.

URLCache

The data you send over the network has the potential to be cached in memory and on device storage. You can go to great lengths to protect your network communications, as we have been doing, only to find out that the communication is being stored. 

Various versions of iOS have had some unexpected behaviour when it comes to the cache settings, and some of the rules for what gets cached in iOS keep changing over the versions. While caching helps network performance by reducing the number of requests, turning it off for any data you think is highly sensitive can be a good idea. You can remove the shared cache at any time (such as on app startup) by calling:

To disable caching on a global level, use:

And if you are using URLSession, you can disable cache for the session like this:

If you are using an NSURLConnection object with a delegate, you can disable the cache per connection with this delegate method:

And to create a URL request that will not check the cache, use:

Various versions of iOS 8 had some bugs where some of these methods on their own would do nothing. That means it's a good idea to implementing all of the above code for sensitive connections, when you need to reliably prevent caching of network requests.

The Future

It is important to understand the limits of HTTPS for protecting network communications. 

In most cases, HTTPS stops at the server. For example, my connection to a corporation's server may be over HTTPS, but once that traffic hits the server, it is unencrypted. This means that the corporation will be able to see the information that was sent (in most cases it needs to), and it also means that company could then proxy or pass that information out again unencrypted. 

I can't finish this article without covering one more concept that is a recent trend—what is called "end-to-end encryption". A good example is an encrypted chat app where two mobile devices are communicating with each other through a server. The two devices create public and private keys—they exchange public keys, while their private keys never leave the device. The data is still sent over HTTPS through the server, but it is first encrypted by the other party's public key in such a way that only the devices holding the private keys can decrypt each other's messages. 

As an analogy to help you understand end-to-end encryption, imagine that I want someone to send me a message securely that only I can read. So I provide them a box with an open padlock on it (the public key) while I keep the padlock key (private key). The user writes a message, puts it in the box, locks the padlock, and sends it back to me. Only I can read what the message is because I am the only one with the key to unlock the padlock. 

With end-to-end encryption, the server provides a service for communication, but it can not read the content of the communication—they ship the locked box, but they don't have the key to open it. While the implementation details are beyond the scope of this article, it's a powerful concept if you want to allow secure communication between users of your app. 

If you want to learn more about this approach, a place to start is the GitHub repo for Open Whisper System, an open-source project.

Conclusion

Almost all mobile apps today will communicate across a network, and security is a critically important but often neglected aspect of mobile app development. 

In this article, we've covered some security best practices, including simple HTTPS, application hardening of network communications, data sanitization, and end-to-end encryption. These best practices should serve as a foundation for security when coding your mobile app.

And while you're here, check out some of our other popular iOS app tutorials and courses!

2017-04-12T19:00:00.000Z2017-04-12T19:00:00.000ZCollin Stuart

Create a Blackjack Game in Swift 3 and SpriteKit

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

In this tutorial you'll create a blackjack game in SpriteKit using Swift 3. You'll learn about implementing touch, creating visual animations, and many other concepts that will come in handy when building a SpriteKit game.

1. Creating the Project and Importing Resources

Open up Xcode and choose Create a new Xcode project or choose New > Project... from the File menu. Make sure iOS is selected and choose the Game template.

new_project

Next, choose whatever you wish for the Product Name, Organization Name, and Organization Identifier. Make sure that Language is set to Swift, Game Technology is set to SpriteKit, and Devices is set to iPad.

project_options

Specify a location to save the project files and click Create.

Importing the Helper Classes

Download the GitHub repo for this project. Inside it you will see a classes folder. Open this folder and drag all the files onto the folder that has the name of whatever you named your project, for example, blackjack. Make sure Copy items if needed is checked as well as the main target in the list of targets.

File options with Copy items if needed box checked

Importing the Images

Also within the tutorial GitHub repo is a folder named tutorial images. Inside the project navigator, open Assets.xcassets and drag all the images into the sidebar. Xcode will automatically create texture atlases from these images.

Tutorial images folder in GitHub

2. Setting Up the Project

Within the project navigator there are two files you can delete (Gamescene.sks and Actions.sks).Delete these two files and select Move To Trash. These files are used by Xcode's built-in scene editor, which can be used to visually lay out your projects. We will be creating everything through code, though, so these files are not needed.

Open GameViewController.swift, delete its contents, and replace it with the following.

The GameViewController class inherits from UIViewController and will have an SKView as its view. Inside the viewDidLoad method, we downcast the view property to an SKView instance, using the as! type cast operator, and configure the view.

If you were to run this project when you created it fresh, you might notice text in the bottom right of the screen. That is what the showsFPS and showsNodeCount properties are for, showing the frames per second the game is running at and the number of SKNodes visible in the scene. We do not need this information, so we set them to false.

The ignoreSiblingOrder property is used to determine the drawing order of the SKNodes within the game. We set this to false here because we need our SKNodes to draw in the order they are added to the scene.

Lastly, we set the scale mode to .aspectFill, which will cause the scene's content to scale to fill the entire screen. We then invoke the presentScene(_:) method on the skView which presents or "shows" the scene.

Next, delete everything in GameScene.swift and replace it with the following.

You can now test the project, and you should be presented with a blank black screen. In the next step we will begin adding content to our scene.

3. Variables and Constants

Enter the following code at the start of the GameScene class right beneath where GameScene inherits from SKScene.

We are creating a number of SKSpriteNodes here. SKSpriteNodes are used to create a colored node, or more commonly from an SKTexture, which is most often an image. We use the convenience initializer init(color:size:) to create a clear colored node moneyContainer. The moneyContainer will be used to hold the money the player bets, and at the end of each round we will animate this moving toward whoever won the game. Placing all the money in this single node makes it easy to animate all the money at one time.

Next, we create the constants dealBtn, hitBtn, and standBtn. As the names suggest, these will be used in game to deal, hit, and stand respectively. We are using the convenience initializer init(imageNamed:), which takes as a parameter the name of the image without an extension.

We then create the three constants money10, money25, and money50, which are of the type Money. Money is a custom class that extends SKSpriteNode and depending on the type of moneyValue passed as a parameter creates one of three different money types. The moneyValue parameter is of type MoneyValue, which is an enum. Have a look at the Money class in the project GitHub repo to see how this all works.

Lastly we create an SKLabelNode using the convenience initializer  init(text:) which takes as a parameter the text to be shown within the label.

4. Implementing setupTable

Add the following beneath the didMove(to:) function.

Here we initialize a constant table and add it to the scene using addChild(_:) which takes as a parameter the node to add to the scene. We set the table's position within the scene and set its zPosition to -1. The zPosition property controls the order in which the nodes are drawn. The lowest number is drawn first, with higher numbers being drawn in order. Because we need the table below everything else, we set its zPosition to -1. This ensures that it is drawn before any other nodes.

We also add the moneyContainer and instructionText to the scene. We set the fontColor of the instructionText to black (the default is white).

Update didMove(to:) to the following.

The didMove(to:) method is called immediately after the scene is presented by the view. Generally, this is where you will do the setup for your scene and create your assets. If you test now, you should see that table and instructionText has been added to the scene. The moneyContainer is there as well but you cannot see it because we created it with a clear color.

5. Implementing setupMoney

Add the following beneath the setupTable method.

Here we simply add the money instances and set their position. Invoke this method within didMove(to:).

6. Implementing setupButtons

Add the following beneath the setupMoney method you created in the step above.

As we did with the moneys in the previous step, we add the buttons and set their positions. Here we use the name property so that we will be able to identify each button through code. We also set the hitBtn and standBtn to be hidden, or invisible, by setting the isHidden property to true.

Now invoke this method within didMove(to:).

If you run the app now, you should see the money instances and buttons have been added to the scene.

7. Implementing touchesBegan

We need to implement the touchesBegan(_:with:) method to be able to tell when any objects in the scene have been touched. This method is called when one or more fingers have touched down on the screen. Add the following within touchesBegan.

The multiTouchEnabled property of the scene's view is set to false by default, which means the view only receives the first touch of a multitouch sequence. With this property disabled, you can retrieve the touch by using the first computed property of the touches set since there is only one object in the set.

We can get the touchLocation within the scene by the location property of the touch. We can then figure out which node was touched by invoking atPoint(_:) and passing in the touchLocation.

We check if the touchedNode's name property is equal to "money", and if it is we know they have touched on one of the three money instances. We initialize a money constant by downcasting the touchedNode to Money, and then we call the bet method invoking the getValue() method on the money constant.

8. Implementing bet

Enter the following beneath the setupButtons function you created in the step above.

We first make sure the player is not trying to bet more money than they have, and if they are we simply return from the function. Otherwise, we add the betAmount to the pot, create a constant tempMoney, set its anchorPoint to (0,0), and add it to the moneyContainer. We then set its position and hide the dealBtn by setting its isHidden property to false.

SKSpriteNodes have an anchorPoint property that defaults to (0.5,0.5). The coordinate system places (0,0) at the bottom left and (1,1) at the top right. You would change this property from its default if you were rotating the SKSpriteNode and wanted it to rotate around a different point. For example, if you changed the anchorPoint property to (0,0) then the SKSpriteNode would rotate from its bottom left corner. You'll often change this property to help with positioning, as we have here.

We need to create an instance of the Pot and Player classes for this code to work. Add the following along with the other constants and variables.

If you test now you can press on any of the moneys and have it added to the moneyContainer.

9. Implementing deal

Add the following along with the rest of your constants and variables.

The allCards array will be used to hold all the cards within the game. This will make it easy to loop through them and remove them from the scene all in one go. The dealerCardsY and playerCardsY constants are the positions of the cards on the y axis. This will help us when placing new cards. The currentPlayerType is used to indicate who to deal to next. It will either be equal to dealer or player1

Inside didMove(to:), add the following.

In the previous code, we initialized currentPlayerType to an unnamed instance of the Player class. Here we set it to player1

We need to create a new deck of cards before we implement the deal method. Enter the following within setupTable.

Now we can implement the deal function. Add the following beneath the bet method.

This method is quite large, but necessary to implement the dealing logic. Let's take it step by step. We initialize a tempCard constant to an instance of Card, set its position, and add it to the scene. We need this card drawn at a zPosition greater than 0, because the dealer's first card needs to be at 0. We set this to an arbitrary number—100 will do. We also create a newCard constant by invoking the deck's getTopCard() method.

Next, we initialize two variables, whichPosition and whichHand, and then run through some logic to determine their final values. We then add the newCard to the appropriate hand (either the player's or dealer's). The xPos constant determines the final x position of the card once it is finished animating.

The SKAction class has a number of class methods you can call to change a node's properties such as position, scale, and rotation. Here we call the move(to:duration:) method, which will move the node from one position to another. However, to actually execute the SKAction, you have to invoke the run(_:) method of a node and pass in the SKAction as a parameter. Here, however, we are invoking the run(_:completion:) method, which will cause the code within the completion closure to run after the action completes execution.

After the action has run to completion, we allow the player to bet by invoking setCanBet(canBet:) on the player1 instance. We then check if the currentPlayerType is an instance of Dealer, and check that the dealer only has one card by invoking hand.getLength(). If this is the case, we set the dealer's first card, which we will need at the end of the game. 

Because the dealer's first card is always face down until the end of the game, we need a reference to the first card so we can show it later. We add this card to the allCards array so we can remove it later, and then set its zPosition property to 0 as we need this card below all the other cards. (Remember the other cards have z-position 100.)

If the currentPlayerType is not an instance of  Dealer, and the length of the hand is not equal to 1, then we remove the tempCard and put the newCard in the same position, making sure to set its zPosition to 100.

According to the rules of blackjack, both the dealer and the player get two cards to start the game off with. Here we are checking what the currentPlayerType is and changing it to the opposite. Because the dealer has less than two cards, we invoke the deal function again. Otherwise, we check if both dealer and player1 have two cards, and if this is the case, we check to see if either has cards with a total value of 21—a winning hand. If either has 21 then the game is over because one of them has gotten blackjack. If neither has 21 then we show the standBtn and hitBtn and the game continues.

The rules of blackjack state that the dealer must stand at 17 or greater. The next few lines of code check if the dealer's hand value is less than 17 and if so invokes the deal method. If it is 17 or greater then the game is over. Lastly, if player1's hand value is greater than 21 then the game is over because they have busted.

This was a lot of logic to go through! If anything is unclear, just read it again and take your time to understand it. 

Next, we need to implement the gameover method.

We need to be able to tell when the user has pressed on the deal button. Add the following code to the touchesBegan(_:with:) method.

10. Implementing doGameOver

Next, enter the following beneath the deal method you created in the step above.

We get the x and y position of the first card in the allCards array, which is the dealer's first card. Then we instantiate a constant tempCard by invoking getFirstCard on the dealer. Remember we set this Card earlier in the deal method? Here we add it to the scene, set its position using the tempCardX and tempCardY constants, and set its zPosition to 0so it is beneath the other cards.

We need to know who won the game, so we initialize a variable winner setting it equal to player1, though this may change depending on if the dealer actually won the game.

We then run through some logic to determine who won the game. If hasBlackjack parameter was true then we figure out who won and return from the function. Otherwise, we continue through the logic to figure out who won the game. I am not going to go step by step through this logic as it should be clear to understand. No matter who won, we invoke moveMoneyContainer(position:), which takes as a parameter the position to move the money container to. This will be the y position of either the dealer's or player1's cards.

11. Implementing moveMoneyContainer

Enter the following code beneath the doGameOver method.

The moveMoneyContainer(position:) method moves the moneyContainer to whoever won the game, either the player or the dealer. When the SKAction completes, we invoke resetMoneyContainer.

12. Implementing resetMoneyContainer

The resetMoneyContainer method removes all the moneys by invoking the removeAllChildren() method, resets the moneyContainer to its original position, and invokes newGame.

13. Implementing newGame

Add the following beneath the resetMoneyContainer method you implemented in the step above.

Here we reset all the necessary variables and remove all the cards from the scene by looping through the allCards array and invoking removeFromParent() on each element.

14. Implementing the hitBtn and standBtn

All that is left to complete our game is to implement the touches on the hitBtn and standBtn. Enter the following within the touchesBegan(_:with:) method.

And now we'll implement the methods called in the event handler. Enter the following two methods below the newGame method.

Within the hit method, we make sure that player can bet, and if that is the case, we set the currentPlayerType to player1, and then invoke the deal method and stop the player betting further.

Within the stand method, we invoke setYielding on player1, passing in true. We then check if the dealer's hand value is less than 17, and if that is the case we call deal, and if the dealer's hand is 17 or greater it means the game is over.

You can now test the completed game.

Conclusion

This was a long tutorial with a good bit of logic tucked away in the deal method. We did not implement using the Pot and adding and subtracting money from the player's bank. Why don't you try doing that as an exercise to finish the app?

You now have a blackjack game to be proud of. Thank you for reading, and I hope you found this tutorial useful. While you're here, check out some of our other courses and tutorials about app programming with Swift and SpriteKit!

2017-04-13T17:00:00.000Z2017-04-13T17:00:00.000ZJames Tyner

Create a Blackjack Game in Swift 3 and SpriteKit

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

In this tutorial you'll create a blackjack game in SpriteKit using Swift 3. You'll learn about implementing touch, creating visual animations, and many other concepts that will come in handy when building a SpriteKit game.

1. Creating the Project and Importing Resources

Open up Xcode and choose Create a new Xcode project or choose New > Project... from the File menu. Make sure iOS is selected and choose the Game template.

new_project

Next, choose whatever you wish for the Product Name, Organization Name, and Organization Identifier. Make sure that Language is set to Swift, Game Technology is set to SpriteKit, and Devices is set to iPad.

project_options

Specify a location to save the project files and click Create.

Importing the Helper Classes

Download the GitHub repo for this project. Inside it you will see a classes folder. Open this folder and drag all the files onto the folder that has the name of whatever you named your project, for example, blackjack. Make sure Copy items if needed is checked as well as the main target in the list of targets.

File options with Copy items if needed box checked

Importing the Images

Also within the tutorial GitHub repo is a folder named tutorial images. Inside the project navigator, open Assets.xcassets and drag all the images into the sidebar. Xcode will automatically create texture atlases from these images.

Tutorial images folder in GitHub

2. Setting Up the Project

Within the project navigator there are two files you can delete (Gamescene.sks and Actions.sks).Delete these two files and select Move To Trash. These files are used by Xcode's built-in scene editor, which can be used to visually lay out your projects. We will be creating everything through code, though, so these files are not needed.

Open GameViewController.swift, delete its contents, and replace it with the following.

The GameViewController class inherits from UIViewController and will have an SKView as its view. Inside the viewDidLoad method, we downcast the view property to an SKView instance, using the as! type cast operator, and configure the view.

If you were to run this project when you created it fresh, you might notice text in the bottom right of the screen. That is what the showsFPS and showsNodeCount properties are for, showing the frames per second the game is running at and the number of SKNodes visible in the scene. We do not need this information, so we set them to false.

The ignoreSiblingOrder property is used to determine the drawing order of the SKNodes within the game. We set this to false here because we need our SKNodes to draw in the order they are added to the scene.

Lastly, we set the scale mode to .aspectFill, which will cause the scene's content to scale to fill the entire screen. We then invoke the presentScene(_:) method on the skView which presents or "shows" the scene.

Next, delete everything in GameScene.swift and replace it with the following.

You can now test the project, and you should be presented with a blank black screen. In the next step we will begin adding content to our scene.

3. Variables and Constants

Enter the following code at the start of the GameScene class right beneath where GameScene inherits from SKScene.

We are creating a number of SKSpriteNodes here. SKSpriteNodes are used to create a colored node, or more commonly from an SKTexture, which is most often an image. We use the convenience initializer init(color:size:) to create a clear colored node moneyContainer. The moneyContainer will be used to hold the money the player bets, and at the end of each round we will animate this moving toward whoever won the game. Placing all the money in this single node makes it easy to animate all the money at one time.

Next, we create the constants dealBtn, hitBtn, and standBtn. As the names suggest, these will be used in game to deal, hit, and stand respectively. We are using the convenience initializer init(imageNamed:), which takes as a parameter the name of the image without an extension.

We then create the three constants money10, money25, and money50, which are of the type Money. Money is a custom class that extends SKSpriteNode and depending on the type of moneyValue passed as a parameter creates one of three different money types. The moneyValue parameter is of type MoneyValue, which is an enum. Have a look at the Money class in the project GitHub repo to see how this all works.

Lastly we create an SKLabelNode using the convenience initializer  init(text:) which takes as a parameter the text to be shown within the label.

4. Implementing setupTable

Add the following beneath the didMove(to:) function.

Here we initialize a constant table and add it to the scene using addChild(_:) which takes as a parameter the node to add to the scene. We set the table's position within the scene and set its zPosition to -1. The zPosition property controls the order in which the nodes are drawn. The lowest number is drawn first, with higher numbers being drawn in order. Because we need the table below everything else, we set its zPosition to -1. This ensures that it is drawn before any other nodes.

We also add the moneyContainer and instructionText to the scene. We set the fontColor of the instructionText to black (the default is white).

Update didMove(to:) to the following.

The didMove(to:) method is called immediately after the scene is presented by the view. Generally, this is where you will do the setup for your scene and create your assets. If you test now, you should see that table and instructionText has been added to the scene. The moneyContainer is there as well but you cannot see it because we created it with a clear color.

5. Implementing setupMoney

Add the following beneath the setupTable method.

Here we simply add the money instances and set their position. Invoke this method within didMove(to:).

6. Implementing setupButtons

Add the following beneath the setupMoney method you created in the step above.

As we did with the moneys in the previous step, we add the buttons and set their positions. Here we use the name property so that we will be able to identify each button through code. We also set the hitBtn and standBtn to be hidden, or invisible, by setting the isHidden property to true.

Now invoke this method within didMove(to:).

If you run the app now, you should see the money instances and buttons have been added to the scene.

7. Implementing touchesBegan

We need to implement the touchesBegan(_:with:) method to be able to tell when any objects in the scene have been touched. This method is called when one or more fingers have touched down on the screen. Add the following within touchesBegan.

The multiTouchEnabled property of the scene's view is set to false by default, which means the view only receives the first touch of a multitouch sequence. With this property disabled, you can retrieve the touch by using the first computed property of the touches set since there is only one object in the set.

We can get the touchLocation within the scene by the location property of the touch. We can then figure out which node was touched by invoking atPoint(_:) and passing in the touchLocation.

We check if the touchedNode's name property is equal to "money", and if it is we know they have touched on one of the three money instances. We initialize a money constant by downcasting the touchedNode to Money, and then we call the bet method invoking the getValue() method on the money constant.

8. Implementing bet

Enter the following beneath the setupButtons function you created in the step above.

We first make sure the player is not trying to bet more money than they have, and if they are we simply return from the function. Otherwise, we add the betAmount to the pot, create a constant tempMoney, set its anchorPoint to (0,0), and add it to the moneyContainer. We then set its position and hide the dealBtn by setting its isHidden property to false.

SKSpriteNodes have an anchorPoint property that defaults to (0.5,0.5). The coordinate system places (0,0) at the bottom left and (1,1) at the top right. You would change this property from its default if you were rotating the SKSpriteNode and wanted it to rotate around a different point. For example, if you changed the anchorPoint property to (0,0) then the SKSpriteNode would rotate from its bottom left corner. You'll often change this property to help with positioning, as we have here.

We need to create an instance of the Pot and Player classes for this code to work. Add the following along with the other constants and variables.

If you test now you can press on any of the moneys and have it added to the moneyContainer.

9. Implementing deal

Add the following along with the rest of your constants and variables.

The allCards array will be used to hold all the cards within the game. This will make it easy to loop through them and remove them from the scene all in one go. The dealerCardsY and playerCardsY constants are the positions of the cards on the y axis. This will help us when placing new cards. The currentPlayerType is used to indicate who to deal to next. It will either be equal to dealer or player1

Inside didMove(to:), add the following.

In the previous code, we initialized currentPlayerType to an unnamed instance of the Player class. Here we set it to player1

We need to create a new deck of cards before we implement the deal method. Enter the following within setupTable.

Now we can implement the deal function. Add the following beneath the bet method.

This method is quite large, but necessary to implement the dealing logic. Let's take it step by step. We initialize a tempCard constant to an instance of Card, set its position, and add it to the scene. We need this card drawn at a zPosition greater than 0, because the dealer's first card needs to be at 0. We set this to an arbitrary number—100 will do. We also create a newCard constant by invoking the deck's getTopCard() method.

Next, we initialize two variables, whichPosition and whichHand, and then run through some logic to determine their final values. We then add the newCard to the appropriate hand (either the player's or dealer's). The xPos constant determines the final x position of the card once it is finished animating.

The SKAction class has a number of class methods you can call to change a node's properties such as position, scale, and rotation. Here we call the move(to:duration:) method, which will move the node from one position to another. However, to actually execute the SKAction, you have to invoke the run(_:) method of a node and pass in the SKAction as a parameter. Here, however, we are invoking the run(_:completion:) method, which will cause the code within the completion closure to run after the action completes execution.

After the action has run to completion, we allow the player to bet by invoking setCanBet(canBet:) on the player1 instance. We then check if the currentPlayerType is an instance of Dealer, and check that the dealer only has one card by invoking hand.getLength(). If this is the case, we set the dealer's first card, which we will need at the end of the game. 

Because the dealer's first card is always face down until the end of the game, we need a reference to the first card so we can show it later. We add this card to the allCards array so we can remove it later, and then set its zPosition property to 0 as we need this card below all the other cards. (Remember the other cards have z-position 100.)

If the currentPlayerType is not an instance of  Dealer, and the length of the hand is not equal to 1, then we remove the tempCard and put the newCard in the same position, making sure to set its zPosition to 100.

According to the rules of blackjack, both the dealer and the player get two cards to start the game off with. Here we are checking what the currentPlayerType is and changing it to the opposite. Because the dealer has less than two cards, we invoke the deal function again. Otherwise, we check if both dealer and player1 have two cards, and if this is the case, we check to see if either has cards with a total value of 21—a winning hand. If either has 21 then the game is over because one of them has gotten blackjack. If neither has 21 then we show the standBtn and hitBtn and the game continues.

The rules of blackjack state that the dealer must stand at 17 or greater. The next few lines of code check if the dealer's hand value is less than 17 and if so invokes the deal method. If it is 17 or greater then the game is over. Lastly, if player1's hand value is greater than 21 then the game is over because they have busted.

This was a lot of logic to go through! If anything is unclear, just read it again and take your time to understand it. 

Next, we need to implement the gameover method.

We need to be able to tell when the user has pressed on the deal button. Add the following code to the touchesBegan(_:with:) method.

10. Implementing doGameOver

Next, enter the following beneath the deal method you created in the step above.

We get the x and y position of the first card in the allCards array, which is the dealer's first card. Then we instantiate a constant tempCard by invoking getFirstCard on the dealer. Remember we set this Card earlier in the deal method? Here we add it to the scene, set its position using the tempCardX and tempCardY constants, and set its zPosition to 0so it is beneath the other cards.

We need to know who won the game, so we initialize a variable winner setting it equal to player1, though this may change depending on if the dealer actually won the game.

We then run through some logic to determine who won the game. If hasBlackjack parameter was true then we figure out who won and return from the function. Otherwise, we continue through the logic to figure out who won the game. I am not going to go step by step through this logic as it should be clear to understand. No matter who won, we invoke moveMoneyContainer(position:), which takes as a parameter the position to move the money container to. This will be the y position of either the dealer's or player1's cards.

11. Implementing moveMoneyContainer

Enter the following code beneath the doGameOver method.

The moveMoneyContainer(position:) method moves the moneyContainer to whoever won the game, either the player or the dealer. When the SKAction completes, we invoke resetMoneyContainer.

12. Implementing resetMoneyContainer

The resetMoneyContainer method removes all the moneys by invoking the removeAllChildren() method, resets the moneyContainer to its original position, and invokes newGame.

13. Implementing newGame

Add the following beneath the resetMoneyContainer method you implemented in the step above.

Here we reset all the necessary variables and remove all the cards from the scene by looping through the allCards array and invoking removeFromParent() on each element.

14. Implementing the hitBtn and standBtn

All that is left to complete our game is to implement the touches on the hitBtn and standBtn. Enter the following within the touchesBegan(_:with:) method.

And now we'll implement the methods called in the event handler. Enter the following two methods below the newGame method.

Within the hit method, we make sure that player can bet, and if that is the case, we set the currentPlayerType to player1, and then invoke the deal method and stop the player betting further.

Within the stand method, we invoke setYielding on player1, passing in true. We then check if the dealer's hand value is less than 17, and if that is the case we call deal, and if the dealer's hand is 17 or greater it means the game is over.

You can now test the completed game.

Conclusion

This was a long tutorial with a good bit of logic tucked away in the deal method. We did not implement using the Pot and adding and subtracting money from the player's bank. Why don't you try doing that as an exercise to finish the app?

You now have a blackjack game to be proud of. Thank you for reading, and I hope you found this tutorial useful. While you're here, check out some of our other courses and tutorials about app programming with Swift and SpriteKit!

2017-04-13T17:00:00.000Z2017-04-13T17:00:00.000ZJames Tyner

Android Things and Machine Learning

$
0
0

Android Things allows you to make amazing IoT devices with simple code, but one of the things that can make a device extraordinary is machine learning. While there are a few services available online that will allow you to upload data and will return results, being able to use machine learning locally and offline can be incredibly useful. 

In this article, I'll share some of my experiences using the TensorFlow image classifier, starting with Google's Android Things TensorFlow example

Why Use Machine Learning?

Machine learning can help solve problems that conventional apps cannot. To provide context, let's go through a simple example where machine learning can be used with an IoT device to improve daily life.

Here in Colorado, it’s not uncommon to see news articles about wildlife coming out from the mountains and walking around a downtown:

News story of a moose in downtown Boulder Colorado

Or bears climbing trees at the local university:

News article of a bear at CU Boulder in Colorado

I've even had a friend post video of a bear outside of their home!

Snapshot from a video of a bear outside of a home

While these situations are usually taken care of without issue, there is public data available from the State of Colorado’s Division of Parks and Wildlife that details black bear-human conflicts, and various wildlife species activity/ranges. By looking at the black bear-human conflict data in Google Earth, we can find areas where bear encounters can be a risk for public safety.

Colorado bear-human conflict map

In addition, while I was reading up on wildlife data in the state, a friend posted an image of her car after having an accident involving an elk during her drive down to Durango, CO. According to the Colorado Department of Transportation (CDOT) Crash Book, just over 4,000 accidents involving wildlife occurred over one year in Colorado, with about 150 injuries and one fatality. In the entire United States, this number jumps to 725,000 to 1,500,000 accidents with about 200 human fatalities a year, according to the Defenders of Wildlife facts sheet.

Car after hitting an elk near Durango Colorado

So how can we use machine learning to help solve this problem? With image recognition, we can create a motion-triggered device that can take a picture with a Raspberry Pi and then analyze it to detect a potentially dangerous wild animal.

Using the Google sample, we can create an Android Things device that takes pictures with a Raspberry Pi and classifies the content of those pictures against over a thousand possible labels. But these labels don't exactly match what we'd need to use. 

By training TensorFlow to use our own images and labels, we can create a device that can identify an elk, moose or black bear, and then perform an action if one is detected. This allows us to make a device that can potentially save lives, while still being simple to create.

Creating a Custom TensorFlow Image Classifier

After you have installed and run Google's TensorFlow for Android Things sample, it's time to start modifying it. The first thing you will want to do is ensure that TensorFlow is on your computer and working. This can be fairly complex, and the easiest way I have found to make it work properly through the entire process of generating trained files is to install and use Docker. This program will allow you to run virtual machines on your computer that are preconfigured for TensorFlow. 

Once you have installed Docker and have it running on your computer, you should open its preferences and set memory usage for your virtual machines. I set mine to use 7 GB of memory, which may be more than you need, but I spent days attempting to get TensorFlow to properly create the required trained graphs without crashing before I realized that the virtual machine was running out of memory.

What we will be doing in this example is retraining the existing machine learning example to use our own data, as this is much faster than training a new dataset from scratch. For a more detailed explanation of what we're doing, you can take a look at the official TensorFlow documentation.

Docker advanced settings screen

Once you've installed Docker and started it on your machine, you'll need to run it from a terminal and pull down an image. For this example I am running under macOS, so the commands may be a bit different for your platform.

When everything has finished setting up, you should have a prompt in your terminal similar to this:

At this point you'll need a set of images to train TensorFlow with. I used the Fatkun Batch Download Image Chrome plugin to download returned images from a Google search en masse. When you have the plugin installed, you can search for whatever you want to classify and start to select images that you would want to save.

Chrome plugin screen for downloading bulk images

To make naming a little easier, you may also want to go into the More Options section and let the plugin rename the images while downloading them.

Bulk image download rename setting

Next you will need to move the images that you are using into a folder in tf_files under your home directory, which is a folder we created while initializing our docker machine. For this example, my images directory is called TensorFlowTrainingImages. Each classifiable item should have its own folder within that directory, as shown below.

TensorFlow training images folder structure

Once your directories are set up, you can start retraining with the following command from your Docker terminal:

The above command will generate bottlenecks, which are essentially data used by the final classification data pass, and a graph and labels file that are used for classification. 

From this point forward, the operations we run with TensorFlow can take anywhere from a few minutes to over an hour, depending on the speed of your computer. This might be a good time to make coffee or go for a quick walk. 

As the retraining command runs, you should see a lot of output in your terminal similar to this:

Once your bottlenecks have been generated, you will have a graph.pb file and a labels.txt file that represents your data. While these formats work great when running classification on your computer, they tend to not work when placed into an Android app. You will need to optimize them.

Start by running the following command. Accept all the default values.

Once configuration has finished, run the following command to set up the optimization tool. This step took about an hour on my machine, so patience is key!

Once your optimization tool is built, you can use it to optimize your graph file.

Now that your optimized graph is generated, you can find it with your labels in the tf_files folder in your home directory.

Contents of TensorFlow directory after generating machine learning data

Adding Your Custom Classifier to the Android Things Sample

Congratulations! Generating the TensorFlow graph and labels is the hard part, and may take some finagling to make generate properly. Now that you have them, it's time to edit the Android Things sample project to use your own data. First, go into the app's build.gradle file and remove the following section, as well as its plugin declaration:

The above code downloads Google's sample graph and labels and adds them to the assets directory. Since we've generated our own, we don't need to worry about those and can delete those lines. 

Next, open the TensorFlowImageClassifier.java file. You should see a few declared variables towards the top of the file, with a long comment about what will need to be changed if you're using your own graphs that were generated from a code lab (which is close enough to what we did above).

Change the last part of MODEL_FILE and LABEL_FILE to match the name of your optimized graph and label.

Back to the long comment in the original source, let's go ahead and edit the file to match Google's recommendations.

You'll notice that we're setting NUM_CLASSES to 4. This is the number of items available for our machine learning algorithm to classify. You can change this to match the number of classification categories you've trained with.

To wrap things up, move your optimized graph file and labels into the app/src/main/assets directory. Once that's done, you can install the sample app onto a Raspberry Pi with a camera module and give it a shot. Below is a picture I took with the device:

Picture of a bear taken with Android Things device

And the results that were sent to Firebase (with some slight modifications to the sample app).

Output data from machine learning classification of image
As you can see, the device successfully identified the black bear in the picture!

Conclusion

In this tutorial you got a brief introduction to using TensorFlow for machine learning and integrating it into an Android Things app. As you've seen, machine learning is a powerful tool that can be used to solve various problems that a conventional app would struggle with. When combining machine learning with the Internet of Things, you can create some amazing and useful devices that interact with the world around them. 

Using what you've learned from this article, and others in the Android Things series, you can build some really amazing new apps and devices!

2017-04-17T17:00:00.000Z2017-04-17T17:00:00.000ZPaul Trebilcox-Ruiz

Android Things and Machine Learning

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

Android Things allows you to make amazing IoT devices with simple code, but one of the things that can make a device extraordinary is machine learning. While there are a few services available online that will allow you to upload data and will return results, being able to use machine learning locally and offline can be incredibly useful. 

In this article, I'll share some of my experiences using the TensorFlow image classifier, starting with Google's Android Things TensorFlow example

Why Use Machine Learning?

Machine learning can help solve problems that conventional apps cannot. To provide context, let's go through a simple example where machine learning can be used with an IoT device to improve daily life.

Here in Colorado, it’s not uncommon to see news articles about wildlife coming out from the mountains and walking around a downtown:

News story of a moose in downtown Boulder Colorado

Or bears climbing trees at the local university:

News article of a bear at CU Boulder in Colorado

I've even had a friend post video of a bear outside of their home!

Snapshot from a video of a bear outside of a home

While these situations are usually taken care of without issue, there is public data available from the State of Colorado’s Division of Parks and Wildlife that details black bear-human conflicts, and various wildlife species activity/ranges. By looking at the black bear-human conflict data in Google Earth, we can find areas where bear encounters can be a risk for public safety.

Colorado bear-human conflict map

In addition, while I was reading up on wildlife data in the state, a friend posted an image of her car after having an accident involving an elk during her drive down to Durango, CO. According to the Colorado Department of Transportation (CDOT) Crash Book, just over 4,000 accidents involving wildlife occurred over one year in Colorado, with about 150 injuries and one fatality. In the entire United States, this number jumps to 725,000 to 1,500,000 accidents with about 200 human fatalities a year, according to the Defenders of Wildlife facts sheet.

Car after hitting an elk near Durango Colorado

So how can we use machine learning to help solve this problem? With image recognition, we can create a motion-triggered device that can take a picture with a Raspberry Pi and then analyze it to detect a potentially dangerous wild animal.

Using the Google sample, we can create an Android Things device that takes pictures with a Raspberry Pi and classifies the content of those pictures against over a thousand possible labels. But these labels don't exactly match what we'd need to use. 

By training TensorFlow to use our own images and labels, we can create a device that can identify an elk, moose or black bear, and then perform an action if one is detected. This allows us to make a device that can potentially save lives, while still being simple to create.

Creating a Custom TensorFlow Image Classifier

After you have installed and run Google's TensorFlow for Android Things sample, it's time to start modifying it. The first thing you will want to do is ensure that TensorFlow is on your computer and working. This can be fairly complex, and the easiest way I have found to make it work properly through the entire process of generating trained files is to install and use Docker. This program will allow you to run virtual machines on your computer that are preconfigured for TensorFlow. 

Once you have installed Docker and have it running on your computer, you should open its preferences and set memory usage for your virtual machines. I set mine to use 7 GB of memory, which may be more than you need, but I spent days attempting to get TensorFlow to properly create the required trained graphs without crashing before I realized that the virtual machine was running out of memory.

What we will be doing in this example is retraining the existing machine learning example to use our own data, as this is much faster than training a new dataset from scratch. For a more detailed explanation of what we're doing, you can take a look at the official TensorFlow documentation.

Docker advanced settings screen

Once you've installed Docker and started it on your machine, you'll need to run it from a terminal and pull down an image. For this example I am running under macOS, so the commands may be a bit different for your platform.

When everything has finished setting up, you should have a prompt in your terminal similar to this:

At this point you'll need a set of images to train TensorFlow with. I used the Fatkun Batch Download Image Chrome plugin to download returned images from a Google search en masse. When you have the plugin installed, you can search for whatever you want to classify and start to select images that you would want to save.

Chrome plugin screen for downloading bulk images

To make naming a little easier, you may also want to go into the More Options section and let the plugin rename the images while downloading them.

Bulk image download rename setting

Next you will need to move the images that you are using into a folder in tf_files under your home directory, which is a folder we created while initializing our docker machine. For this example, my images directory is called TensorFlowTrainingImages. Each classifiable item should have its own folder within that directory, as shown below.

TensorFlow training images folder structure

Once your directories are set up, you can start retraining with the following command from your Docker terminal:

The above command will generate bottlenecks, which are essentially data used by the final classification data pass, and a graph and labels file that are used for classification. 

From this point forward, the operations we run with TensorFlow can take anywhere from a few minutes to over an hour, depending on the speed of your computer. This might be a good time to make coffee or go for a quick walk. 

As the retraining command runs, you should see a lot of output in your terminal similar to this:

Once your bottlenecks have been generated, you will have a graph.pb file and a labels.txt file that represents your data. While these formats work great when running classification on your computer, they tend to not work when placed into an Android app. You will need to optimize them.

Start by running the following command. Accept all the default values.

Once configuration has finished, run the following command to set up the optimization tool. This step took about an hour on my machine, so patience is key!

Once your optimization tool is built, you can use it to optimize your graph file.

Now that your optimized graph is generated, you can find it with your labels in the tf_files folder in your home directory.

Contents of TensorFlow directory after generating machine learning data

Adding Your Custom Classifier to the Android Things Sample

Congratulations! Generating the TensorFlow graph and labels is the hard part, and may take some finagling to make generate properly. Now that you have them, it's time to edit the Android Things sample project to use your own data. First, go into the app's build.gradle file and remove the following section, as well as its plugin declaration:

The above code downloads Google's sample graph and labels and adds them to the assets directory. Since we've generated our own, we don't need to worry about those and can delete those lines. 

Next, open the TensorFlowImageClassifier.java file. You should see a few declared variables towards the top of the file, with a long comment about what will need to be changed if you're using your own graphs that were generated from a code lab (which is close enough to what we did above).

Change the last part of MODEL_FILE and LABEL_FILE to match the name of your optimized graph and label.

Back to the long comment in the original source, let's go ahead and edit the file to match Google's recommendations.

You'll notice that we're setting NUM_CLASSES to 4. This is the number of items available for our machine learning algorithm to classify. You can change this to match the number of classification categories you've trained with.

To wrap things up, move your optimized graph file and labels into the app/src/main/assets directory. Once that's done, you can install the sample app onto a Raspberry Pi with a camera module and give it a shot. Below is a picture I took with the device:

Picture of a bear taken with Android Things device

And the results that were sent to Firebase (with some slight modifications to the sample app).

Output data from machine learning classification of image
As you can see, the device successfully identified the black bear in the picture!

Conclusion

In this tutorial you got a brief introduction to using TensorFlow for machine learning and integrating it into an Android Things app. As you've seen, machine learning is a powerful tool that can be used to solve various problems that a conventional app would struggle with. When combining machine learning with the Internet of Things, you can create some amazing and useful devices that interact with the world around them. 

Using what you've learned from this article, and others in the Android Things series, you can build some really amazing new apps and devices!

2017-04-17T17:00:00.000Z2017-04-17T17:00:00.000ZPaul Trebilcox-Ruiz

15 Best Ionic App Templates

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

With Ionic, creating a high-performance, cross-platform mobile app is as easy as creating a website. In fact, if you are a seasoned web developer who wants to become an Android or iOS app developer overnight, all you have to do is install and start using Ionic. I assure you, you'll take to it like a fish to water.

Building a feature-rich Ionic app with an elegant user interface, however, can be challenging—even more so if it is to look native on multiple platforms. Fortunately, by using an Ionic template you can save substantial amounts of time and effort.

CodeCanyon is one of the largest online marketplaces for Ionic templates. No matter what your app's requirements are, there's a good chance that CodeCanyon has a template for it. In this article, I'm going to list 15 outstanding Ionic templates you should consider using this year.

1. Ionic Mobile App Builder

Ionic Mobile App Builder

Developed by CodeGenerator, Ionic Mobile App Builder, or IMA builder for short, is an award-winning template that lets you create both static and dynamic Ionic apps without writing any code whatsoever. It offers a very intuitive web-based interface you can use to define every aspect of your app. More precisely, it allows you to simply fill out a few forms in your browser to create and configure all the components of your app's user interface, including navigation drawers, menus, popovers, tables, and pages.

The best thing about this template, however, is that the apps you build with it will be capable of interacting with a variety of data sources, such as WordPress, WooCommerce, and any other content management system that has a JSON API.

2. IonWordpress

IonWordpress

IonWordpress, developed by elite author IonicThemes, is the template to use if you want to convert your WordPress blog into a stunning Android or iOS app. This is one of the most popular themes on CodeCanyon, and for a good reason—it has more features than you can imagine, great documentation, and easy-to-read code.

In addition to WordPress-related functionality, this template also offers push notifications, mobile advertisements via Google AdMob and Apple iAd, and an in-app browser.

3. Material Design UI Ionic

Material Design UI Ionic

This template, developed by elite author CreativeForm, is for Ionic developers who don't want to spend time designing their apps. It offers over 60 commonly used screen layouts and five beautiful UI themes. It also has a well-organized Sass file containing dozens of variables you can change to further customize your app's looks.

To help you avoid dealing with multiple resolutions of images, this template includes icon fonts with over 800 icons. If you must use images, it also supports several blending modes for them.

4. IonStore

IonStore

IonStore, developed by ionicpremium, is a template you should definitely consider using if you are creating an e-commerce app. It allows you to quickly create a beautiful app that can connect to your WooCommerce website and pull data and settings from it. It supports multiple payment methods, languages, and currencies. It is also highly customizable, offering you fine-grained control over the looks of your app. And as if that wasn't enough, it also supports discount badges, user registration, order tracking, and push notifications.

It is also worth mentioning that this template is very well-documented, and sees regular updates and bug fixes.

5. Catalogue Ionic

Catalogue Ionic

Catalogue Ionic, developed by appseed, is a generic business-oriented template. If you run a business and are trying to build an app that can showcase your products, this template might be just what you need. It also allows you to display useful information such as your shop's opening hours and your contact options. If you're using WooCommerce already, this template can be configured to read data from it.

Catalogue Ionic's architecture is extremely modular. Furthermore, because it was built using a very popular Yeoman generator for the Ionic framework, you can be sure that it follows several best practices.

6. Barebone Ionic

Barebone Ionic

Barebone Ionic is a large, feature-rich starter template developed by appseed. As a developer, you can use it to kickstart almost any kind of Ionic app. For example, it allows you to effortlessly create apps that can read data from various content management systems, such as WordPress and Drupal. It can also serve as a good foundation for CRUD-oriented apps, instant messaging apps, and e-commerce apps.

I should also add that this template is fully integrated with the APIs of several popular websites, such as YouTube, Instagram, Facebook, and Vimeo.

7. IonChat

IonChat

IonChat, as its name suggests, is a template that lets you build cross-platform instant messaging apps. Developed by IonCoder, this is a large template offering dozens of powerful features, such as support for group conversations, social login, and friend management.

Not only is this template easily customizable, the apps you create with it will be powered by Firebase, a cloud-based platform that's owned by Google. That means you can use the Firebase console to manage your app data.

8. Ionic Framework App

Ionic 2 App

If you are looking for a modern template with dozens of beautiful pages and a wide variety of useful features, this template, created by gtsopour, is for you. Built with Ionic 3, it is very modular and extremely easy to extend. In fact, it has over 20 modules and over 35 components!

The apps you create with this template will be able to communicate with your WordPress blog using its REST API. They'll also be able to display charts, YouTube videos, Google maps, and RSS feeds. Another impressive fact about the template is that it offers a barcode scanner module, which you can use to scan several types of barcodes.

9. TapShop

TapShop

By using TapShop, a template created by tapgadget, you can effortlessly create an e-commerce app that allows your users to buy and sell products. It has all the features you'd expect from this type of template. 

For instance, it has screens for buyers to browse through available products, make offers to vendors, and even chat with vendors. Similarly, it has screens for vendors to post new products, upload photos of those products, and handle offers made by buyers. 

But there's more to this template than just that. It supports push notifications, and is fully integrated with AdMob too, allowing you to easily monetize the apps you create with it.

10. Restaurant Ionic

Restaurant Ionic

Restaurant Ionic, developed by appseed, is a template that's bound to entice any restaurant owner. Apps created with it are feature-packed, and have intuitive user interfaces that let customers view menus, place customized orders, read about special offers, and choose delivery methods. They'll also allow you to communicate with your customers using push notifications.

Setting this template up is a breeze. So is customizing it, because you can dramatically change the looks of your app by simply selecting one of the several beautiful Material Design-inspired color themes it offers.

11. Ionium

Ionium

Ionium is a multi-purpose starter template created by ionicpremium. Whether you are building an e-commerce app, a hotel booking app, a news reader, or even a social media app, this template has got you covered. It also allows you to quickly create CRUD-oriented apps, which support both local and remote storage.

Because this template uses Material Design components, animations, and gestures, you can be sure that the apps you create with it will look very modern and polished.

12. IonSocialApp

IonSocialApp

Apps with social features tend to be more successful on both Google Play and Apple's App Store. If you are interested in creating one yourself, IonSocialApp, another template developed by IonicThemes, has everything you need to get started. It offers screens that allow users to sign up, sign in, create posts, write comments, and even browse through trending topics.

This template also includes several useful features that can improve your app's user interface. For instance, it supports the pull-to-refresh gesture, infinite scrolling, and native sharing functionality.

13. Mobionic

Mobionic

Mobionic, developed by gtsopour, is another multipurpose template with a host of useful features. It is integrated with WordPress and supports server-side pagination of posts. It also has multiple layouts for your app's home screen. The latest version of this template is fully integrated with the YouTube API too, allowing you to create video-based apps.

Additionally, it supports push notifications for both the Android and iOS platforms.

14. IcyMobi

IcyMobi

IcyMobi, from inspitheme, is a one-stop shop for all your e-commerce app development needs. With this template, you can create apps that support many popular payment methods, order tracking, inventory management, and push notifications.

They'll also be able to interact with multiple e-commerce platforms, such as PrestaShop, WooCommerce, and Magento. Furthermore, if you want your app to display posts from your WordPress blog, this template allows that too.

15. Daily News

Daily News

Developed by tdmobile, this is an easy-to-use template that lets you create WordPress-based news apps. In addition to a beautiful home-screen, this template has screens to display photo galleries, search results, comments, bookmarks, and more.

It also has several notifications-related features, such as delivery tracking, analytics, and segmented targeting.

Conclusion

In this article, you learned about 15 premium Ionic templates you can use to jumpstart your app development process. But don't limit yourself to just them because CodeCanyon has hundreds more of such templates. So what are you waiting for? Grab a template now and get building!

And if you want to learn more about Ionic or app templates, we've got lots of great tutorials and courses right here at Envato Tuts+!


2017-04-18T12:00:00.000Z2017-04-18T12:00:00.000ZAshraff Hathibelagal

New Course: Code a Mobile App With NativeScript

$
0
0

Our new short course, Code a Mobile App With NativeScript, will quickly get you up and running with NativeScript, a useful framework for building cross-platform native mobile apps. 

Code a Mobile App With NativeScript screenshot

What You’ll Learn

NativeScript allows developers to use JavaScript, TypeScript or Angular to build apps for iOS and Android. Unlike Cordova, which uses WebView for rendering the UI of the app, NativeScript uses the native platform's rendering engine and accesses the native APIs, so that it provides a truly native user experience.

In this course, Keyvan Kasaei will introduce you to NativeScript and show you step by step how to build a simple application. Along the way, you'll learn how to implement a simple app workflow with network requests, an MVVM architecture, and some of the most important NativeScript UI components. By the end, you'll understand why you should consider NativeScript for your next mobile app project.

Watch the Introduction

 

Take the Course

You can take our new course straight away with a free 10-day trial of our monthly subscription. If you decide to continue, it costs just $15 a month, and you’ll get access to hundreds of courses, with new ones added every week.

You can also strengthen your JavaScript development muscles with some of the fantastic JavaScript plugins and scripts over on Envato Market.

2017-04-18T12:28:15.000Z2017-04-18T12:28:15.000ZAndrew Blackman

New Course: Code a Mobile App With NativeScript

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

Our new short course, Code a Mobile App With NativeScript, will quickly get you up and running with NativeScript, a useful framework for building cross-platform native mobile apps. 

Code a Mobile App With NativeScript screenshot

What You’ll Learn

NativeScript allows developers to use JavaScript, TypeScript or Angular to build apps for iOS and Android. Unlike Cordova, which uses WebView for rendering the UI of the app, NativeScript uses the native platform's rendering engine and accesses the native APIs, so that it provides a truly native user experience.

In this course, Keyvan Kasaei will introduce you to NativeScript and show you step by step how to build a simple application. Along the way, you'll learn how to implement a simple app workflow with network requests, an MVVM architecture, and some of the most important NativeScript UI components. By the end, you'll understand why you should consider NativeScript for your next mobile app project.

Watch the Introduction

 

Take the Course

You can take our new course straight away with a free 10-day trial of our monthly subscription. If you decide to continue, it costs just $15 a month, and you’ll get access to hundreds of courses, with new ones added every week.

You can also strengthen your JavaScript development muscles with some of the fantastic JavaScript plugins and scripts over on Envato Market.

2017-04-18T12:28:15.000Z2017-04-18T12:28:15.000ZAndrew Blackman

Quick Tip: Working With Custom Fonts in Android O

$
0
0

The first developer preview of Android O is here!

In this series, we’re looking at some of the up-and-coming UI features that you can start experimenting with today, via the Android O Developer Preview.

In the first tip, I showed you how to set up your development to support this early O preview, and how to create text that automatically scales up and scales down to suit the current screen configuration. In this tip, we’re going to be looking at how Android O is about to make working with custom fonts a hassle-free experience.

Adding Custom Fonts to Your Project

Have you ever wanted to make a particular piece of text stand out? Or maybe you were convinced that a custom font would be the perfect way to add some extra personality to your application?

While there are many benefits to using custom fonts, working with them in Android has traditionally been a painful experience, requiring you to either use a library or create a custom View

Thankfully, working with custom fonts in Android is about to get much easier, as custom fonts are set to become a fully supported resource type in Android O. This means that adding a custom font to your app will be as straightforward as adding any other resource, such as images and text.

To follow along with this tutorial, you’ll need some font files that you can add to the Android O project we created in part one.

Android O supports both .otf (OpenType) and .ttf (TrueType) formats. There are plenty of websites offering these kinds of fonts for free, so spend a few minutes searching Google until you find a font you like.

Since we’re just experimenting with Android O’s new features, it doesn’t particularly matter which font you use, but when you’re looking for fonts to use in production releases of your app then you should always check that font’s terms and conditions. Just because a resource is free to download doesn’t automatically mean there aren’t restrictions on how you can use and redistribute this resource, so always check the fine print!

You should also consider your application’s purpose, content and target audience, as different fonts convey different messages. If you’re designing an app to help people complete their tax returns, then your audience may struggle to take your app’s financial and legal advice seriously if it’s delivered in a weird and wacky font!

Once you’ve found a font you want to work with, download and unzip it. At this point, you should check the font’s filename for invalid characters—essentially anything that isn’t lowercase a-z, 0-9 or an underscore. Try to include any other characters, and Android Studio will throw an error as soon as you try to reference that resource.  

Once you have your font file(s), you’ll need somewhere to store them:

  • Right-click your project’s app/res folder and select New > Android resource directory.
  • Open the dropdown menu and select font.
  • Enter font as the File name.
  • Click OK.
Create a resfont folder in Android Studio
  • Drag and drop your font file(s) into your new res/font folder.

Using Your Custom Fonts

You can apply a custom font to your text using the new android:fontFamily XML attribute:

Test your custom font on your Android O AVD

You can also add custom fonts to any styles you’ve created in your app:

If you want to use custom fonts programmatically, then you can retrieve a custom font using the getFont(int) method, for example:

Creating a Font Family

Sometimes you may unzip a font folder and discover multiple versions of the same font, such as an italicized version, or fonts with varying weights and thicknesses.

If you’re using multiple versions of the same font, then you may want to group them together into a font family. A font family is essentially a dedicated XML file where you define each version of the font, along with its associated style and weight attributes.

To create a font family:

  • Make sure you’ve added all the font files to your project’s res/font folder.
  • Right-click your project’s res/font folder, and then select New > Font resource file.
  • Give this file a name, and then click OK.
  • Open this XML file and define all the different versions of this font, along with their style and weight attributes, for example:

You can then reference any of the fonts in this family using the android:fontFamily attribute. For example:

Don’t Forget to Test!

While it’s easy to get carried away with new features, don’t go overboard with custom fonts! Consistent UIs are easier to navigate and understand, and if your app is constantly switching between fonts then your users may end up paying more attention to how your text looks, rather than what it says.

If you do include custom fonts in your project, then it’s important to test how that font renders across a wide range of different screen configurations, as your top priority should always be ensuring that your text is easy to read.

Conclusion

In this tip, I showed you how to create more stylish and unique text, by adding custom fonts to your projects. In the final post in this series, we’re going to shift our focus from text to images, as I show you how to create adaptive launcher icons that automatically adapt their shape to suit the current device.

In the meantime, check out some of our other tutorials on Android app development!

2017-04-19T15:55:48.000Z2017-04-19T15:55:48.000ZJessica Thornsby

Quick Tip: Working With Custom Fonts in Android O

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

The first developer preview of Android O is here!

In this series, we’re looking at some of the up-and-coming UI features that you can start experimenting with today, via the Android O Developer Preview.

In the first tip, I showed you how to set up your development to support this early O preview, and how to create text that automatically scales up and scales down to suit the current screen configuration. In this tip, we’re going to be looking at how Android O is about to make working with custom fonts a hassle-free experience.

Adding Custom Fonts to Your Project

Have you ever wanted to make a particular piece of text stand out? Or maybe you were convinced that a custom font would be the perfect way to add some extra personality to your application?

While there are many benefits to using custom fonts, working with them in Android has traditionally been a painful experience, requiring you to either use a library or create a custom View

Thankfully, working with custom fonts in Android is about to get much easier, as custom fonts are set to become a fully supported resource type in Android O. This means that adding a custom font to your app will be as straightforward as adding any other resource, such as images and text.

To follow along with this tutorial, you’ll need some font files that you can add to the Android O project we created in part one.

Android O supports both .otf (OpenType) and .ttf (TrueType) formats. There are plenty of websites offering these kinds of fonts for free, so spend a few minutes searching Google until you find a font you like.

Since we’re just experimenting with Android O’s new features, it doesn’t particularly matter which font you use, but when you’re looking for fonts to use in production releases of your app then you should always check that font’s terms and conditions. Just because a resource is free to download doesn’t automatically mean there aren’t restrictions on how you can use and redistribute this resource, so always check the fine print!

You should also consider your application’s purpose, content and target audience, as different fonts convey different messages. If you’re designing an app to help people complete their tax returns, then your audience may struggle to take your app’s financial and legal advice seriously if it’s delivered in a weird and wacky font!

Once you’ve found a font you want to work with, download and unzip it. At this point, you should check the font’s filename for invalid characters—essentially anything that isn’t lowercase a-z, 0-9 or an underscore. Try to include any other characters, and Android Studio will throw an error as soon as you try to reference that resource.  

Once you have your font file(s), you’ll need somewhere to store them:

  • Right-click your project’s app/res folder and select New > Android resource directory.
  • Open the dropdown menu and select font.
  • Enter font as the File name.
  • Click OK.
Create a resfont folder in Android Studio
  • Drag and drop your font file(s) into your new res/font folder.

Using Your Custom Fonts

You can apply a custom font to your text using the new android:fontFamily XML attribute:

Test your custom font on your Android O AVD

You can also add custom fonts to any styles you’ve created in your app:

If you want to use custom fonts programmatically, then you can retrieve a custom font using the getFont(int) method, for example:

Creating a Font Family

Sometimes you may unzip a font folder and discover multiple versions of the same font, such as an italicized version, or fonts with varying weights and thicknesses.

If you’re using multiple versions of the same font, then you may want to group them together into a font family. A font family is essentially a dedicated XML file where you define each version of the font, along with its associated style and weight attributes.

To create a font family:

  • Make sure you’ve added all the font files to your project’s res/font folder.
  • Right-click your project’s res/font folder, and then select New > Font resource file.
  • Give this file a name, and then click OK.
  • Open this XML file and define all the different versions of this font, along with their style and weight attributes, for example:

You can then reference any of the fonts in this family using the android:fontFamily attribute. For example:

Don’t Forget to Test!

While it’s easy to get carried away with new features, don’t go overboard with custom fonts! Consistent UIs are easier to navigate and understand, and if your app is constantly switching between fonts then your users may end up paying more attention to how your text looks, rather than what it says.

If you do include custom fonts in your project, then it’s important to test how that font renders across a wide range of different screen configurations, as your top priority should always be ensuring that your text is easy to read.

Conclusion

In this tip, I showed you how to create more stylish and unique text, by adding custom fonts to your projects. In the final post in this series, we’re going to shift our focus from text to images, as I show you how to create adaptive launcher icons that automatically adapt their shape to suit the current device.

In the meantime, check out some of our other tutorials on Android app development!

2017-04-19T15:55:48.000Z2017-04-19T15:55:48.000ZJessica Thornsby

Swift From Scratch: Inheritance and Protocols

$
0
0

If you've read the previous lessons of this series, you should have a good grasp of the fundamentals of the Swift programming language by now. We talked about variables, constants, and functions, and in the previous lesson we covered the basics of object-oriented programming in Swift.

While playgrounds are a great tool to play with Swift and learn the language, it's time to move on and create our first Swift project in Xcode. In this lesson, we're going to create the foundation of a simple to-do application using Xcode and Swift. Along the way, we'll learn more about object-oriented programming and we'll also take a closer look at the integration of Swift and Objective-C.

Prerequisites

If you'd like to follow along with me, then make sure that you have Xcode 8.3.2 or higher installed on your machine. Xcode 8.3.2 is available from Apple's App Store.

1. Project Setup

Step 1: Choose a Template

Launch Xcode 8.3.2 or higher and select New > Project... from the File menu. From the iOS section, choose the Single View Application template and click Next.

Setting Up the Project In Xcode

Step 2: Configure the Project

Name the project ToDo and set Language to Swift. Make sure Devices is set to iPhone and the checkboxes at the bottom are unchecked. Click Next to continue.

Configuring the Project In Xcode

Tell Xcode where you'd like to store your project and click Create in the bottom right to create your first Swift project.

2. Project Anatomy

Before we continue our journey into Swift, let's take a moment to see what Xcode has created for us. If you're new to Xcode and iOS development, then most of this will be new to you. By working with a Swift project, however, you will get a better feeling of what classes and structures look like and how they behave in Swift.

The project template doesn't differ much from a project created with Objective-C as the programming language. The most important differences are related to the AppDelegate and ViewController classes.

If you've worked with Objective-C in the past, then you'll notice that the project template contains fewer files. There are no header (.h) or implementation (.m) files to be found in our project. In Swift, classes have no separate header file in which the interface is declared. Instead, a class is declared and implemented in a single .swift file.

Our project currently contains two Swift files, one for the AppDelegate class, AppDelegate.swift, and another one for the ViewController class, ViewController.swift. The project also includes two storyboards, Main.storyboard and LaunchScreen.storyboard. We'll work with the main storyboard a bit later in this lesson. It currently only contains the scene for the ViewController class.

There are a few other files and folders included in the project, but we're going to ignore those for now. They play no important role in the scope of this lesson.

3. Inheritance

The first thing we'll touch upon in this lesson is inheritance, a common paradigm in object-oriented programming. In Swift, only classes can inherit from another class. In other words, structures and enumerations don't support inheritance. This is one of the key differences between classes and structures.

Open ViewController.swift to see inheritance in action. The interface and implementation of the ViewController class is pretty bare-bones, which makes it easier for us to focus on the essentials.

UIKit

At the top of ViewController.swift, you should see an import statement for the UIKit framework. Remember that the UIKit framework provides the infrastructure for creating a functional iOS application. The import statement at the top makes this infrastructure available to us in ViewController.swift.

Superclass

Below the import statement, we define a new class named ViewController. The colon after the class name doesn't translate to is of type as we saw earlier in this series. Instead, the class after the colon is the superclass of the ViewController class. In other words, the following snippet could be read as we define a class named ViewController that inherits from UIViewController.

This also explains the presence of the import statement at the top of ViewController.swift since the UIViewController class is defined in the UIKit framework.

Overrides

The ViewController class currently includes two methods, but notice that each method is prefixed with the override keyword. This indicates that the methods are defined in the class's superclass—or higher up the inheritance tree—and are overridden by the ViewController class.

The override construct doesn't exist in Objective-C. In Objective-C, you implement an overridden method in a subclass without explicitly indicating that it overrides a method higher up the inheritance tree. The Objective-C runtime takes care of the rest.

While the same is true in Swift, the override keywords adds safety to method overriding. Because we've prefixed the viewDidLoad() method with the override keyword, Swift expects this method in the class's superclass or higher up the inheritance tree. Simply put, if you override a method that doesn't exist in the inheritance tree, the compiler will throw an error. You can test this by misspelling the viewDidLoad() method as shown below.

Compiler Error

4. User Interface

Declaring Outlets

Let's add a table view to the view controller to display a list of to-do items. Before we do that, we need to create an outlet for the table view. An outlet is nothing more than a property that's visible to and can be set in Interface Builder. To declare an outlet in the ViewController class, we prefix the property, a variable, with the @IBOutlet attribute.

Note that the outlet is an implicitly unwrapped optional. A what? Let me start by saying that an outlet always needs to be an optional type. The reason is simple. Every property of the ViewController class needs to have a value after initialization. An outlet, however, is only connected to the user interface at runtime after the ViewController instance has been initialized hence the optional type.

Wait a minute. The tableView outlet is declared as an implicitly unwrapped optional, not an optional. No problem. We can declare the tableView outlet as an optional by replacing the exclamation mark in the above snippet with a question mark. That would compile just fine. However, this would also mean that we would need to explicitly unwrap the property every time we want to access the value stored in the optional. This would quickly become cumbersome and verbose.

Instead, we declare the tableView outlet as an implicitly unwrapped optional, which means that we don't need to explicitly unwrap the optional if we need to access its value. In short, an implicitly unwrapped optional is an optional, but we can access the value stored in the optional like a regular variable. The important thing to keep in mind is that your application will crash if you try to access its value if no value has been set. That's the gotcha. If the outlet is properly connected, however, we can be sure that the outlet is set when we first try to access it.

Connecting Outlets

With the outlet declared, it's time to connect it in Interface Builder. Open Main.storyboard, and select the view controller. Choose Embed In > Navigation Controller from the Editor menu. This sets the view controller as the root view controller of a navigation controller. Don't worry about this for now.

Drag a UITableView instance from the Object Library to the view controller's view, and add the necessary layout constraints. With the table view selected, open the Connections Inspector and set the table view's dataSource and delegate outlets to the view controller.

Adding a Table View

With the Connections Inspector still open, select the view controller and connect the tableView outlet to the table view we just added. This connects the tableView outlet of the ViewController class to the table view.

5. Protocols

Before we can build and run the application, we need to implement the UITableViewDataSource and UITableViewDelegate protocols in the ViewController class. This involves several things.

Step 1: Conforming to Protocols

We need to tell the compiler that the ViewController class conforms to the UITableViewDataSource and UITableViewDelegate protocols. The syntax looks similar to that in Objective-C.

The protocols the class conforms to are listed after the superclass, UIViewController in the above example. If a class doesn't have a superclass, which isn't uncommon in Swift, then the protocols are listed immediately after the class name and colon.

Step 2: Implementing the UITableViewDataSource Protocol

Because the UITableViewDelegate protocol doesn't define required methods, we're only going to implement the UITableViewDataSource protocol for now. Before we do, let's create a variable property to store the to-do items we're going to list in the table view.

We declare a variable property items of type [String] and set an empty array, [], as the initial value. This should look familiar by now. Next, let's implement the two required methods of the UITableViewDataSource protocol.

The first required method, numberOfRows(inSection:), is easy. We simply return the number of items stored in the items property.

The second required method, cellForRow(at:), needs an explanation. Using subscript syntax, we ask items for the item that corresponds with the current row.

We then ask the table view for a cell with identifier "TableViewCell", passing in the index path for the current row. Note that we store the cell in a constant, cell. There's no need to declare cell as a variable.

In the next line of code, we configure the table view cell, setting the text label's text with the value of item. Note that in Swift the textLabel property of UITableViewCell is declared as an optional type hence the question mark. This line of code could be read as set the text label's text property to item if textLabel is not equal to nil. In other words, the text label's text property is only set if textLabel isn't nil. This is a very convenient safety construct in Swift known as optional chaining.

Step 3: Cell Reuse

There are two things we need to sort out before building the application. First, we need to tell the table view that it needs to use the UITableViewCell class to create new table view cells. We do this by invoking registerClass(_:forCellReuseIdentifier:), passing in the UITableViewCell class and the reuse identifier we used earlier, "TableViewCell". Update the viewDidLoad() method as shown below.

Step 4: Adding Items

We currently don't have any items to show in the table view. This is easily solved by populating the items property with a few to-do items. There are several ways to accomplish this. I've chosen to populate the items property in the viewDidLoad() method as shown below.

6. Build and Run

It's time to take our application for a spin. Select Run from Xcode's Product menu or hit Command-R. If you've followed along, you should end up with the following result.

Completed App

Note that I've added a title, To Do, at the top of the view in the navigation bar. You can do the same by setting the title property of the ViewController instance in the viewDidLoad() method.

Conclusion

Even though we've just created a simple application, you've learned quite a few new things. We've explored inheritance and overriding methods. We also covered protocols and how to adopt the UITableViewDataSource protocol in the ViewController class. The most important thing you've learned, however, is how to interact with Objective-C APIs.

It's important to understand that the APIs of the iOS SDK are written in Objective-C. Swift was designed to be compatible with these APIs. Based on past failures, Apple understood that Swift needed to be able to hook into the iOS SDK without having to rewrite every single API in Swift.

Combining Objective-C and Swift is possible, but there are some caveats that we'll explore in more detail as we move forward. Because of Swift's relentless focus on safety, we need to take a few hurdles from time to time. However, none of these hurdles are too great as we'll find out in the next lesson in which we continue working on our to-do application.

In the meantime, check out some of our other courses and tutorials about Swift language iOS development!

2017-04-20T20:37:25.600Z2017-04-20T20:37:25.600ZBart Jacobs

The Right Way to Share State Between Swift View Controllers

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

A few years ago, when I was still an employee in a mobile consultancy, I worked on an app for a big investment bank. Big companies, especially banks, usually have processes in place to ensure that their software is secure, robust, and maintainable.

Part of this process involved sending the code of the app I wrote to a third party for review. That didn’t bother me, because I thought my code was impeccable and that the review company would say the same.

When their response came back, the verdict was different than I thought. Although they said the quality of the code was not bad, they pointed to the fact that the code was hard to maintain and to test (unit testing was not very popular in iOS development back then).

I dismissed their judgement, thinking that my code was great and there was no way it could be improved. They must just not understand it!

I had the typical developer hubris: we often think that what we do is great and others don’t get it. 

In hindsight I was wrong. Not much later, I started reading about some best practices. From then on, the problems in my code started to stick out like a sore thumb. I realized that, like many iOS developers, I had succumbed to some classic pitfalls of bad coding practices.

What Most iOS Developers Get Wrong

One of the most common iOS development bad practices arises when passing state between the view controllers of an app. I myself have fallen into this trap in the past.

State propagation across view controllers is vital in any iOS app. As your users navigate through the screens of your app and interact with it, you need to keep a global state that tracks all the changes the user makes to the data.

And this is where most iOS developers reach for the obvious, but incorrect, solution: the singleton pattern.

The singleton pattern is very quick to implement, especially in Swift, and it works well. You just have to add a static variable to a class to keep a shared instance of the class itself, and you are done.

It is then easy to access this shared instance from anywhere in your code:

For this reason, many developers think they found the best solution to the problem of state propagation. But they are wrong.

The singleton pattern is actually considered an anti-pattern. There have been many discussions of this in the development community. For example, see this Stack Overflow question.

In a nutshell, singletons create these problems:

  • They introduce a lot of dependencies in your classes, making it harder to change them in the future.
  • They make global state accessible to any part of your code. This can create complex interactions that are hard to track and cause many unexpected bugs.
  • They make your classes very hard to test, since you cannot separate them from a singleton easily.

At this point, some developers think: “Ah, I have a better solution. I will use the AppDelegate instead”.

The problem is that the AppDelegate class in iOS apps is accessed through the UIApplication shared instance:

But the shared instance of UIApplication is itself a singleton. So you haven't solved anything!

The solution to this problem is dependency injection. Dependency injection means that a class does not retrieve or create its own dependencies, but it receives them from the outside.

To see how to use dependency injection in iOS apps and how it can enable state sharing, we first need to revisit one of the fundamental architectural patterns of iOS apps: the Model-View-Controller pattern.

Extending the MVC Pattern

The MVC pattern, in a nutshell, states that there are three layers in the architecture of an iOS app:

  • The model layer represents the data of an app.
  • The view layer shows information on the screen and allows interaction.
  • The controller layer acts as glue between the other two layers, moving data between them.

The usual representation of the MVC pattern is something like this:

Simplistic view of the MVC pattern

The problem is that this diagram is wrong.

This “secret” hides in plain sight in a couple of lines in Apple’s documentation:

“One can merge the MVC roles played by an object, making an object, for example, fulfill both the controller and view roles—in which case, it would be called a view controller. In the same way, you can also have model-controller objects.”

Many developers think that view controllers are the only controllers that exist in an iOS app. For this reason, a lot of code ends up being written inside them for lack of a better place. This is what brings developers to use singletons when they need to propagate state: it seems like the only possible solution.

From the lines quoted above, it is clear that we can add a new entity to our understanding of the MVC pattern: the model controller. Model controllers deal with the model of the app, fulfilling the roles that the model itself should not fulfil. This is actually how the above scheme should look:

Diagram of the MVC pattern updated with view and model controllers

The perfect example of when a model controller is useful is for keeping the app’s state. The model should represent only the data of your app. The app’s state should not be its concern.

This state keeping usually ends inside view controllers, but now we have a new and better place to put it: a model controller. This model controller can then be passed to view controllers as they come on the screen through dependency injection.

We have solved the singleton anti-pattern. Let’s see our solution in practice with an example.

Propagating State Across View Controllers Using Dependency Injection

We're going to write a simple app to see a concrete example of how this works. The app is going to show your favorite quote on one screen, and allow you to edit the quote on a second screen.

This means that our app will need two view controllers, which will need to share state. After you see how this solution works, you can expand the concept to apps of any size and complexity.

To start, we need a model type to represent the data, which in our case is a quote. This can be done with a simple struct:

The Model Controller

We then need to create a model controller that holds the state of the app. This model controller needs to be a class. This is because we will need a single instance that we will pass to all our view controllers. Value types like structs get copied when we pass them around, so they clearly are not the right solution.

All our model controller needs in our example is a property where it can keep the current quote. But, of course, in bigger apps model controllers can be more complex than this:

I assigned a default value to the quote property so we will have already something to display on the screen when the app launches. This is not necessary, and you could declare the property to be an optional initialized to nil, if you wish your app to launch with a blank state.

Create the User Interface

We have now the model controller, which will contain the state of our app. Next, we need the view controllers that will represent the screens of our app.

First, we create their user interfaces. This is how the two view controllers look inside the app’s storyboard.

view controllers in the storyboard

The interface of the first view controller is made up of a couple of labels and a button, put together with simple auto layout constraints. (You can read more on auto layout here on Envato Tuts+.)

The interface of the second view controller is the same, but has a text view to edit the text of the quote and a text field to edit the author.

The two view controllers are connected by a single modal presentation segue, which originates from the Edit quote button.

You can explore the interface and the constraints of the view controllers in the GitHub repo.

Code a View Controller With Dependency Injection

We now need to code our view controllers. The important thing that we need to keep in mind here is that they need to receive the model controller instance from the outside, through dependency injection. So they need to expose a property for this purpose.

We can call our first view controller QuoteViewController. This view controller needs a couple of outlets to the labels for the quote and author in its interface.

When this view controller comes on screen, we populate its interface to show the current quote. We put the code to do this in the controller's viewWillAppear(_:) method.

We could have put this code inside the viewDidLoad() method instead, which is quite common. The problem, though, is that viewDidLoad() is called only once, when the view controller is created. In our app, we need to update the user interface of QuoteViewController every time it comes on the screen. This is because the user can edit the quote on the second screen. 

This is why we use the viewWillAppear(_:) method instead of viewDidLoad(). In this way we can update the view controller’s UI each time it appears on the screen. If you want to know more about a view controller’s lifecycle and all the methods that get called, I wrote an article detailing all of them.

The Edit View Controller

We now need to code the second view controller. We will call this one EditViewController.

This view controller is like the previous one:

  • It has outlets for the text view and the text field the user will use to edit the quote.
  • It has a property for the dependency injection of the model controller instance.
  • It populates its user interface before coming on screen.

In this case, I used the viewDidLoad() method because this view controller comes on screen only once.

Sharing the State

We now need to pass the state between the two view controllers and to update it when the user edits the quote.

We pass the app state in the prepare(for:sender:) method of QuoteViewController. This method is triggered by the connected segue when the user taps on the Edit quote button.

Here we pass forward the instance of the ModelController that keeps the state of the app. This is where the dependency injection for the EditViewController happens.

In the EditViewController, we have to update the state to the newly entered quote before we go back to the previous view controller. We can do this in an action connected to the Save button:

Initialize the Model Controller

We are almost done, but you might have noticed that we are still missing something: the QuoteViewController passes the ModelController to the EditViewController through dependency injection. But who gives this instance to the QuoteViewController in the first place? Remember that when using dependency injection, a view controller should not create its own dependencies. These need to come from the outside.

But there is no view controller before the QuoteViewController, because this is the first view controller of our app. We need some other object to create the ModelController instance and to pass it to the QuoteViewController.

This object is the AppDelegate. The role of the app delegate is to respond to the app’s lifecycle methods and configure the app accordingly. One of these methods is application(_:didFinishLaunchingWithOptions:), which gets called as soon as the app launches. That is where we create the instance of the ModelController and pass it to the QuoteViewController:

Our app is now complete. Each view controller gets access to the global state of the app, but we don’t use singletons anywhere in our code.

You can download the Xcode project for this example app in the tutorial GitHub repo.

Conclusions

In this article you've seen how using singletons to propagate the state in an iOS app is a bad practice. Singletons create a lot of problems, despite being very easy to create and use.

We solved the problem by looking more closely at the MVC pattern and understanding the possibilities hidden in it. Through the use of model controllers and dependency injection, we were able to propagate the state of the app across all view controllers without using singletons.

This is a simple example app, but the concept can be generalized to apps of any complexity. This is the standard best practice to propagate state in iOS apps. I now use it in every app I write for my clients.

A few things to keep in mind when you expand the concept to bigger apps:

  • The model controller can save the state of the app, for example in a file. In this way, our data will be remembered every time we close the app. You could also use a more complex storage solution, for example Core Data. My recommendation is to keep this functionality in a separate model controller that only takes care of storage. That controller can then be used by the model controller that keeps the state of the app.
  • In an app with a more complex flow, you will have many containers in your app flow. These are usually navigation controllers, with the occasional tab bar controller. The concept of dependency injection still applies, but you need to take the containers into account. You can either dig into their contained view controllers when performing the dependency injection, or create custom container subclasses that pass the model controller on.
  • If you add networking to your app, this should go in a separate model controller as well. A view controller can perform a network request through this network controller and then pass the resulting data to the model controller that keeps the state. Remember that the role of a view controller is exactly this: to act as a glue object that passes data around between objects.

Stay tuned for more iOS app development tips and best practices!

2017-03-30T17:29:36.000Z2017-03-30T17:29:36.000ZMatteo Manferdini

Swift From Scratch: Inheritance and Protocols

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

If you've read the previous lessons of this series, you should have a good grasp of the fundamentals of the Swift programming language by now. We talked about variables, constants, and functions, and in the previous lesson we covered the basics of object-oriented programming in Swift.

While playgrounds are a great tool to play with Swift and learn the language, it's time to move on and create our first Swift project in Xcode. In this lesson, we're going to create the foundation of a simple to-do application using Xcode and Swift. Along the way, we'll learn more about object-oriented programming and we'll also take a closer look at the integration of Swift and Objective-C.

Prerequisites

If you'd like to follow along with me, then make sure that you have Xcode 8.3.2 or higher installed on your machine. Xcode 8.3.2 is available from Apple's App Store.

1. Project Setup

Step 1: Choose a Template

Launch Xcode 8.3.2 or higher and select New > Project... from the File menu. From the iOS section, choose the Single View Application template and click Next.

Setting Up the Project In Xcode

Step 2: Configure the Project

Name the project ToDo and set Language to Swift. Make sure Devices is set to iPhone and the checkboxes at the bottom are unchecked. Click Next to continue.

Configuring the Project In Xcode

Tell Xcode where you'd like to store your project and click Create in the bottom right to create your first Swift project.

2. Project Anatomy

Before we continue our journey into Swift, let's take a moment to see what Xcode has created for us. If you're new to Xcode and iOS development, then most of this will be new to you. By working with a Swift project, however, you will get a better feeling of what classes and structures look like and how they behave in Swift.

The project template doesn't differ much from a project created with Objective-C as the programming language. The most important differences are related to the AppDelegate and ViewController classes.

If you've worked with Objective-C in the past, then you'll notice that the project template contains fewer files. There are no header (.h) or implementation (.m) files to be found in our project. In Swift, classes have no separate header file in which the interface is declared. Instead, a class is declared and implemented in a single .swift file.

Our project currently contains two Swift files, one for the AppDelegate class, AppDelegate.swift, and another one for the ViewController class, ViewController.swift. The project also includes two storyboards, Main.storyboard and LaunchScreen.storyboard. We'll work with the main storyboard a bit later in this lesson. It currently only contains the scene for the ViewController class.

There are a few other files and folders included in the project, but we're going to ignore those for now. They play no important role in the scope of this lesson.

3. Inheritance

The first thing we'll touch upon in this lesson is inheritance, a common paradigm in object-oriented programming. In Swift, only classes can inherit from another class. In other words, structures and enumerations don't support inheritance. This is one of the key differences between classes and structures.

Open ViewController.swift to see inheritance in action. The interface and implementation of the ViewController class is pretty bare-bones, which makes it easier for us to focus on the essentials.

UIKit

At the top of ViewController.swift, you should see an import statement for the UIKit framework. Remember that the UIKit framework provides the infrastructure for creating a functional iOS application. The import statement at the top makes this infrastructure available to us in ViewController.swift.

Superclass

Below the import statement, we define a new class named ViewController. The colon after the class name doesn't translate to is of type as we saw earlier in this series. Instead, the class after the colon is the superclass of the ViewController class. In other words, the following snippet could be read as we define a class named ViewController that inherits from UIViewController.

This also explains the presence of the import statement at the top of ViewController.swift since the UIViewController class is defined in the UIKit framework.

Overrides

The ViewController class currently includes two methods, but notice that each method is prefixed with the override keyword. This indicates that the methods are defined in the class's superclass—or higher up the inheritance tree—and are overridden by the ViewController class.

The override construct doesn't exist in Objective-C. In Objective-C, you implement an overridden method in a subclass without explicitly indicating that it overrides a method higher up the inheritance tree. The Objective-C runtime takes care of the rest.

While the same is true in Swift, the override keywords adds safety to method overriding. Because we've prefixed the viewDidLoad() method with the override keyword, Swift expects this method in the class's superclass or higher up the inheritance tree. Simply put, if you override a method that doesn't exist in the inheritance tree, the compiler will throw an error. You can test this by misspelling the viewDidLoad() method as shown below.

Compiler Error

4. User Interface

Declaring Outlets

Let's add a table view to the view controller to display a list of to-do items. Before we do that, we need to create an outlet for the table view. An outlet is nothing more than a property that's visible to and can be set in Interface Builder. To declare an outlet in the ViewController class, we prefix the property, a variable, with the @IBOutlet attribute.

Note that the outlet is an implicitly unwrapped optional. A what? Let me start by saying that an outlet always needs to be an optional type. The reason is simple. Every property of the ViewController class needs to have a value after initialization. An outlet, however, is only connected to the user interface at runtime after the ViewController instance has been initialized hence the optional type.

Wait a minute. The tableView outlet is declared as an implicitly unwrapped optional, not an optional. No problem. We can declare the tableView outlet as an optional by replacing the exclamation mark in the above snippet with a question mark. That would compile just fine. However, this would also mean that we would need to explicitly unwrap the property every time we want to access the value stored in the optional. This would quickly become cumbersome and verbose.

Instead, we declare the tableView outlet as an implicitly unwrapped optional, which means that we don't need to explicitly unwrap the optional if we need to access its value. In short, an implicitly unwrapped optional is an optional, but we can access the value stored in the optional like a regular variable. The important thing to keep in mind is that your application will crash if you try to access its value if no value has been set. That's the gotcha. If the outlet is properly connected, however, we can be sure that the outlet is set when we first try to access it.

Connecting Outlets

With the outlet declared, it's time to connect it in Interface Builder. Open Main.storyboard, and select the view controller. Choose Embed In > Navigation Controller from the Editor menu. This sets the view controller as the root view controller of a navigation controller. Don't worry about this for now.

Drag a UITableView instance from the Object Library to the view controller's view, and add the necessary layout constraints. With the table view selected, open the Connections Inspector and set the table view's dataSource and delegate outlets to the view controller.

Adding a Table View

With the Connections Inspector still open, select the view controller and connect the tableView outlet to the table view we just added. This connects the tableView outlet of the ViewController class to the table view.

5. Protocols

Before we can build and run the application, we need to implement the UITableViewDataSource and UITableViewDelegate protocols in the ViewController class. This involves several things.

Step 1: Conforming to Protocols

We need to tell the compiler that the ViewController class conforms to the UITableViewDataSource and UITableViewDelegate protocols. The syntax looks similar to that in Objective-C.

The protocols the class conforms to are listed after the superclass, UIViewController in the above example. If a class doesn't have a superclass, which isn't uncommon in Swift, then the protocols are listed immediately after the class name and colon.

Step 2: Implementing the UITableViewDataSource Protocol

Because the UITableViewDelegate protocol doesn't define required methods, we're only going to implement the UITableViewDataSource protocol for now. Before we do, let's create a variable property to store the to-do items we're going to list in the table view.

We declare a variable property items of type [String] and set an empty array, [], as the initial value. This should look familiar by now. Next, let's implement the two required methods of the UITableViewDataSource protocol.

The first required method, numberOfRows(inSection:), is easy. We simply return the number of items stored in the items property.

The second required method, cellForRow(at:), needs an explanation. Using subscript syntax, we ask items for the item that corresponds with the current row.

We then ask the table view for a cell with identifier "TableViewCell", passing in the index path for the current row. Note that we store the cell in a constant, cell. There's no need to declare cell as a variable.

In the next line of code, we configure the table view cell, setting the text label's text with the value of item. Note that in Swift the textLabel property of UITableViewCell is declared as an optional type hence the question mark. This line of code could be read as set the text label's text property to item if textLabel is not equal to nil. In other words, the text label's text property is only set if textLabel isn't nil. This is a very convenient safety construct in Swift known as optional chaining.

Step 3: Cell Reuse

There are two things we need to sort out before building the application. First, we need to tell the table view that it needs to use the UITableViewCell class to create new table view cells. We do this by invoking registerClass(_:forCellReuseIdentifier:), passing in the UITableViewCell class and the reuse identifier we used earlier, "TableViewCell". Update the viewDidLoad() method as shown below.

Step 4: Adding Items

We currently don't have any items to show in the table view. This is easily solved by populating the items property with a few to-do items. There are several ways to accomplish this. I've chosen to populate the items property in the viewDidLoad() method as shown below.

6. Build and Run

It's time to take our application for a spin. Select Run from Xcode's Product menu or hit Command-R. If you've followed along, you should end up with the following result.

Completed App

Note that I've added a title, To Do, at the top of the view in the navigation bar. You can do the same by setting the title property of the ViewController instance in the viewDidLoad() method.

Conclusion

Even though we've just created a simple application, you've learned quite a few new things. We've explored inheritance and overriding methods. We also covered protocols and how to adopt the UITableViewDataSource protocol in the ViewController class. The most important thing you've learned, however, is how to interact with Objective-C APIs.

It's important to understand that the APIs of the iOS SDK are written in Objective-C. Swift was designed to be compatible with these APIs. Based on past failures, Apple understood that Swift needed to be able to hook into the iOS SDK without having to rewrite every single API in Swift.

Combining Objective-C and Swift is possible, but there are some caveats that we'll explore in more detail as we move forward. Because of Swift's relentless focus on safety, we need to take a few hurdles from time to time. However, none of these hurdles are too great as we'll find out in the next lesson in which we continue working on our to-do application.

In the meantime, check out some of our other courses and tutorials about Swift language iOS development!

2017-04-20T20:37:25.600Z2017-04-20T20:37:25.600ZBart Jacobs

Quick Tip: Introducing Android O’s Adaptive Icons and Pinned Shortcuts

$
0
0

In this series of quick tips we’ve been looking at some of the upcoming UI changes you can start working with today, via the Android O Developer Preview.

In this final post in the series, we’re going to look at how you can create launcher icons that integrate perfectly with the device’s wider UI, and how to create shortcuts that enable users to jump directly to your app’s most important actions, directly from their homescreen.

Creating Adaptive Icons

With the release of Android O, Original Equipment Manufacturers (OEM) such as HTC and Samsung are going to have the option to provide a mask which the system will apply to all application launcher icons. Masks ensure that all the icons that appear on that device have the same shape: if the OEM provides a circular mask then all the application launcher icons will be circular, and if it provides a rounded square (or “squircle”) mask, then all the icons will have rounded corners.

These adaptive icons are intended to provide a more consistent look and feel across the device’s launcher and in other areas where launcher icons feature prominently, such as your device’s Settings and sharing dialogues.

To ensure that your launcher icons display correctly regardless of the mask being used, you’ll need to make a few adjustments.

Before you get started, check that your Manifest’s android:icon attribute is pointing at the image you want to use as your launcher icon:

Each adaptive icon consists of a background layer, a foreground layer, and a mask. The latter is provided by the OEM, but you’ll need to provide the background and foreground layers. For the best results, these layers should be PNGs without any masks or background shadows. Both layers must be 108x108 dpi, but the inner 72x72 dpi is the content that’ll appear within the masked viewport, as the system reserves the outer 36 dpi around the icon for visual effects, such as pulsing or parallax.

Create your background and foreground layers and then add them to your project. Next, create a res/mipmap-anydpi/ic_launcher.xml file and use it to reference the two drawables you want to use as your background and foreground layers, for example:

Test your adaptive icons across various Android O AVDs

Depending on the design of your particular icon, it’s possible that circular masks may cut off some important content. If you suspect that circular masks might pose a problem for your icon, then you can create a dedicated circular icon that the system will use whenever it’s applying a circular mask.  

Create this circular icon, add it your project, and then reference this version of your icon in your project’s Manifest, using the android:roundIcon attribute.

Pinning Shortcuts

Some devices running Android will allow users to pin application shortcuts to their launcher. These shortcuts appear as separate icons that the user launches by tapping, in exactly the same way they interact with regular application launcher icons.

Each application shortcut will reference one or more Intents, which each launch a specific action within your app. This makes pinned shortcuts a great way of allowing users to jump to your app’s most important tasks and content straight from their homescreen. For example, you might create a shortcut that takes the user to the latest save point in your gaming app, or to their most frequently used contact.

There’s no limit to the number of pinned shortcuts you can offer, although to ensure your app doesn’t take over the user’s launcher it’s recommended that you only offer four shortcuts at any one time.

To offer one or more pinned shortcuts, you’ll first need to create an instance of ShortcutManager:

Then, check that the user’s device actually supports pinned shortcuts:

This returns TRUE if the default launcher supports requestPinShortcut.

Assuming that the device does support in-app shortcuts, you can then create a ShortcutInfo object that contains an ID, an intent, and a label for this particular shortcut.

Finally, you pin the shortcut by calling requestPinShortcut().The default launcher will receive this request and then ask the user to approve or deny the pinning operation. If your app needs to know whether the pinning operation was a success, then at this point you can also create a PendingIntent object.

This PendingIntent will only send a resultIntent if the pinning operation is a success. Your app won’t receive a notification if the operation fails.

Once the pin has been created, you can update its content using the updateShortcuts() method. Just be aware that pinned content or actions usually have a shelf-life. In our gaming example, the user may reach the end of the game or delete their save file, at which point your pinned shortcut won’t have any content to display.

While it’s tempting to recycle a pinned shortcut by tweaking its original purpose, it’s far less confusing for the user if you disable shortcuts that are no longer relevant. If a pinned shortcut does reach the end of its life, then you can disable it by calling disableShortcuts().

Conclusion

In this series we’ve looked at some of the Android O user interface updates that you can start experimenting with today by installing the first Developer Preview. In part one, I showed you how to create text that auto scales based on the current screen configuration; in part two we looked at adding custom fonts to your Android projects, and in this final post in the series we’ve covered adaptive icons and pinned shortcuts.

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

2017-04-24T16:16:51.000Z2017-04-24T16:16:51.000ZJessica Thornsby

Quick Tip: Introducing Android O’s Adaptive Icons and Pinned Shortcuts

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

In this series of quick tips we’ve been looking at some of the upcoming UI changes you can start working with today, via the Android O Developer Preview.

In this final post in the series, we’re going to look at how you can create launcher icons that integrate perfectly with the device’s wider UI, and how to create shortcuts that enable users to jump directly to your app’s most important actions, directly from their homescreen.

Creating Adaptive Icons

With the release of Android O, Original Equipment Manufacturers (OEM) such as HTC and Samsung are going to have the option to provide a mask which the system will apply to all application launcher icons. Masks ensure that all the icons that appear on that device have the same shape: if the OEM provides a circular mask then all the application launcher icons will be circular, and if it provides a rounded square (or “squircle”) mask, then all the icons will have rounded corners.

These adaptive icons are intended to provide a more consistent look and feel across the device’s launcher and in other areas where launcher icons feature prominently, such as your device’s Settings and sharing dialogues.

To ensure that your launcher icons display correctly regardless of the mask being used, you’ll need to make a few adjustments.

Before you get started, check that your Manifest’s android:icon attribute is pointing at the image you want to use as your launcher icon:

Each adaptive icon consists of a background layer, a foreground layer, and a mask. The latter is provided by the OEM, but you’ll need to provide the background and foreground layers. For the best results, these layers should be PNGs without any masks or background shadows. Both layers must be 108x108 dpi, but the inner 72x72 dpi is the content that’ll appear within the masked viewport, as the system reserves the outer 36 dpi around the icon for visual effects, such as pulsing or parallax.

Create your background and foreground layers and then add them to your project. Next, create a res/mipmap-anydpi/ic_launcher.xml file and use it to reference the two drawables you want to use as your background and foreground layers, for example:

Test your adaptive icons across various Android O AVDs

Depending on the design of your particular icon, it’s possible that circular masks may cut off some important content. If you suspect that circular masks might pose a problem for your icon, then you can create a dedicated circular icon that the system will use whenever it’s applying a circular mask.  

Create this circular icon, add it your project, and then reference this version of your icon in your project’s Manifest, using the android:roundIcon attribute.

Pinning Shortcuts

Some devices running Android will allow users to pin application shortcuts to their launcher. These shortcuts appear as separate icons that the user launches by tapping, in exactly the same way they interact with regular application launcher icons.

Each application shortcut will reference one or more Intents, which each launch a specific action within your app. This makes pinned shortcuts a great way of allowing users to jump to your app’s most important tasks and content straight from their homescreen. For example, you might create a shortcut that takes the user to the latest save point in your gaming app, or to their most frequently used contact.

There’s no limit to the number of pinned shortcuts you can offer, although to ensure your app doesn’t take over the user’s launcher it’s recommended that you only offer four shortcuts at any one time.

To offer one or more pinned shortcuts, you’ll first need to create an instance of ShortcutManager:

Then, check that the user’s device actually supports pinned shortcuts:

This returns TRUE if the default launcher supports requestPinShortcut.

Assuming that the device does support in-app shortcuts, you can then create a ShortcutInfo object that contains an ID, an intent, and a label for this particular shortcut.

Finally, you pin the shortcut by calling requestPinShortcut().The default launcher will receive this request and then ask the user to approve or deny the pinning operation. If your app needs to know whether the pinning operation was a success, then at this point you can also create a PendingIntent object.

This PendingIntent will only send a resultIntent if the pinning operation is a success. Your app won’t receive a notification if the operation fails.

Once the pin has been created, you can update its content using the updateShortcuts() method. Just be aware that pinned content or actions usually have a shelf-life. In our gaming example, the user may reach the end of the game or delete their save file, at which point your pinned shortcut won’t have any content to display.

While it’s tempting to recycle a pinned shortcut by tweaking its original purpose, it’s far less confusing for the user if you disable shortcuts that are no longer relevant. If a pinned shortcut does reach the end of its life, then you can disable it by calling disableShortcuts().

Conclusion

In this series we’ve looked at some of the Android O user interface updates that you can start experimenting with today by installing the first Developer Preview. In part one, I showed you how to create text that auto scales based on the current screen configuration; in part two we looked at adding custom fonts to your Android projects, and in this final post in the series we’ve covered adaptive icons and pinned shortcuts.

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

2017-04-24T16:16:51.000Z2017-04-24T16:16:51.000ZJessica Thornsby
Viewing all 1836 articles
Browse latest View live