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

New Course: iPhone App Development With Swift

$
0
0

Whether you are a seasoned iOS developer or just getting started, it pays to learn how to use the Swift programming language for your next app. Swift is the future of application development for Apple platforms, and our new course, iPhone App Development With Swift,  is the perfect way to get started.

What You'll Learn

Tuts+ instructor Derek Jensen will teach you how to use Swift to build an iPhone app from scratch. You'll learn the basic concepts behind creating any iPhone app with Swift, and then you’ll build a simple app to practice your skills.

Here's a free preview of some of the lessons from this course:

What You'll Be Building

Throughout the course you will be creating a fully functional iPhone application. This video gives an introduction to the app and its features.

Creating the Basic Layout

In this lesson from section 2, the focus is on creating the basic layout of our application. We will primarily be dealing with three screens to navigate through the different aspects of the news feeds.

Presenting the Feeds

Jumping forward to section 4, this lesson shows you how to take your newly downloaded and parsed news feed and begin to present it to the user. 

Start Learning for Just $15

You can take our new course straight away by subscribing to Tuts+. For just $15 a month, you get access to this course and hundreds of others, with new ones added every week.

2015-03-10T13:59:52.000Z2015-03-10T13:59:52.000ZAndrew Blackman

New Course: iPhone App Development With Swift

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

Whether you are a seasoned iOS developer or just getting started, it pays to learn how to use the Swift programming language for your next app. Swift is the future of application development for Apple platforms, and our new course, iPhone App Development With Swift,  is the perfect way to get started.

What You'll Learn

Tuts+ instructor Derek Jensen will teach you how to use Swift to build an iPhone app from scratch. You'll learn the basic concepts behind creating any iPhone app with Swift, and then you’ll build a simple app to practice your skills.

Here's a free preview of some of the lessons from this course:

What You'll Be Building

Throughout the course you will be creating a fully functional iPhone application. This video gives an introduction to the app and its features.

Creating the Basic Layout

In this lesson from section 2, the focus is on creating the basic layout of our application. We will primarily be dealing with three screens to navigate through the different aspects of the news feeds.

Presenting the Feeds

Jumping forward to section 4, this lesson shows you how to take your newly downloaded and parsed news feed and begin to present it to the user. 

Start Learning for Just $15

You can take our new course straight away by subscribing to Tuts+. For just $15 a month, you get access to this course and hundreds of others, with new ones added every week.

2015-03-10T13:59:52.000Z2015-03-10T13:59:52.000ZAndrew Blackman

Dependency Injection With Dagger 2 on Android

$
0
0

Dependency injection is a software design pattern focused on making our applications loosely coupled, extensible, and maintainable. In this tutorial, you will learn how to handle dependency injection using Dagger 2.

Introduction

When you have an object that needs or depends on another object to do its work, you have a dependency. Dependencies can be solved by letting the dependent object create the dependency or asking a factory object to make one. In the context of dependency injection, however, the dependencies are supplied to the class that needs the dependency to avoid the need for the class itself to create them. This way you create software that is loosely coupled and highly maintainable.

This tutorial uses the newest version of Dagger, Dagger 2. At the time of writing, Dagger 2 isn't officially released yet and is in pre-alpha stage. However, it is usable and stable. You can visit Dagger on GitHub to get news about the project and possible dates for the official release.

Prerequisites

You will need the latest version of Android Studio installed on your development machine, which you can download from the Android Developer website.

1. Dagger 2 API

Dagger 2 exposes a number of special annotations:

  • @Module for the classes whose methods provide dependencies
  • @Provides for the methods within @Module classes
  • @Inject to request a dependency (a constructor, a field, or a method)
  • @Component is a bridge interface between modules and injection

These are the most important annotations you need to know about to get started with dependency injection using Dagger 2. I'm going to show you how to use them in a simple Android application.

2. Dagger 2 Workflow

To implement Dagger 2 correctly, you have to follow these steps:

  1. Identify the dependent objects and its dependencies.
  2. Create a class with the @Module annotation, using the @Provides annotation for every method that returns a dependency.
  3. Request dependencies in your dependent objects using the @Inject annotation.
  4. Create an interface using the @Component annotation and add the classes with the @Module annotation created in the second step.
  5. Create an object of the @Component interface to instantiate the dependent object with its dependencies.

Dependency analysis is shifted from run time to compile time. This means that you are notified of possible problems during the development phase, unlike with other libraries, such as Guice. Before using the Dagger 2 library, you need to prepare your Android Studio installation to access the generated classes.

3. Android Studio Environment Setup

Step 1

Create a new application using Android Studio and give it a name. I've named my project TutsplusDagger.

Step 1 Type a name for the project

Step 2

Set the Minimum SDK for the project to API 10 to reach as many devices as possible.

Step 2 Select minimum SDK

Step 3

Choose the Blank layout for the activity you are creating. For this tutorial, you don't need a special layout.

Step 3 Choose the template for the project

Step 4

Name the activity MainActivity and click Finish.

Step 4 Type a name for the activity

With  the project created, you need to make a few modifications to the gradle files. Let's make those changes in the next step.

4. Configuring Gradle Setup

Step 1

We need to modify the project's build.gradle file as shown below.

Let's take a moment to see what changes we've made:

  • dependencies: In this section, I've added a plugin that is going to be useful for accessing the code generated by Dagger. If you don't, you'll see errors when referring to these new classes.
  • allprojects: This change is necessary since the libraries we're going to use are currently in pre-alpha, and this is the only place available if you want to access them using Maven. You can try to download the Dagger and Dagger Compiler libraries from Sonatype, but this tutorial is based on the Maven repositories.

Step 2

Open build.gradle in your project's app folder and modify it as shown below.

At the beginning of the file, I'm applying the new plugin. Be sure to put the new plugin (com.neenbedankt.android-apt) below or after the Android plugin. If you don't, then it's going to show errors when trying to synchronize the project with the gradle files.

In dependencies I added:

  • dagger library
  • dagger-compiler for code generation
  • javax.annotation for additional annotations required outside Dagger

After updating Dagger's configuration, you can synchronize the project with the gradle files by clicking the button at the top.

Synchronize project with grade files

At this point, you have an empty project ready to be used in your application. If you see any errors, make sure you've correctly followed the above steps. We can now proceed to implement our example project.

5. Implementing Dagger 2

Step 1: Identify Dependent Objects

For this tutorial, I'm going to work with two classes, Vehicle and Motor. Motor is the independent class and Vehicleis the dependent class. I'm going to start creating this model within a new package called model.

This is what the Motor class look like:

This class has only one attribute called rpm, which I'm going to modify through the accelerate and brake methods. And I'll check the current value using the getRpm method.

This is what the Vehicle class looks like:

In this class, you can see that I'm not creating a new object of the Motor class, even though I'm using its methods. In a real world application, this class should have more methods and attributes, but let's keep it simple for now.

Step 2: Create @Module Class

You now have to create a class with the @Module annotation. This class is going to provide the objects you will need with its dependencies satisfied. For this, you have to create a new package (just to keep it in order), name it module and add a new class inside it as follows:

As I specified in Step 1, Vehicle needsMotor to work properly. That is why you need to create two providers, one for Motor (the independent model) and another one for Vehicle (indicating its dependency).

Don't forget that every provider (or method) must have the@Provides annotation and the class must have the @Module annotation. The @Singleton annotation indicates that there will be only one instance of the object.

Step 3: Request Dependencies in Dependent Objects

Now that you have the providers for your different models, you need to request them. Just as Vehicle needs Motor, you have to add the @Inject annotation in the Vehicle constructor as follows:

You can use the @Inject annotation to request dependencies in the constructor, fields, or methods. In this case, I'm keeping the injection in the constructor.

Step 4: Connecting@Modules With @Inject

The connection between the provider of dependencies, @Module, and the classes requesting them through @Inject is made using @Component, which is an interface:

Next to the @Component annotation, you have to specify which modules are going to be used—in this case I use VehicleModule, which we created earlier. If you need to use more modules, then just add them using a comma as a separator.

Within the interface, add methods for every object you need and it will automatically give you one with all its dependencies satisfied. In this case, I only need a Vehicle object, which is why there is only one method.

Step 5: Using @Component Interface to Obtain Objects

Now that you have every connection ready, you have to obtain an instance of this interface and invoke its methods to obtain the object you need. I'm going to implement it in the onCreate method in the MainActivity as follows:

When you try to create a new object of the interface with the @Component annotation, you have to do it using the prefix Dagger_<NameOfTheComponentInterface>, in this case Dagger_VehicleComponent, and then use the builder method to call every module within.

You can see that the magic takes place on line 23. You are only asking for one object of the class Vehicle and the library is the one in charge of satisfying all the dependencies this object needs. Again you can see there is no new instantiation of any other object—everything is managed by the library.

You can now run the app and try it on your device or in an emulator. If you followed the tutorial step by step, you will see a Toast message indicating the initial value or the rpm variable.

In the attached project, you can see a custom user interface for the MainActivity class, in which you can modify the value of the rpm variable by tapping the buttons on the screen.

Conclusion

Dependency injection is a pattern that you will have to implement sooner or later in your own applications. With Dagger 2, you have an easy-to-use library to implement it. I hope you found this tutorial useful, and don't forget to share it if you liked it.

2015-03-11T15:45:11.000Z2015-03-11T15:45:11.000ZKerry Perez Huanca

Dependency Injection With Dagger 2 on Android

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

Dependency injection is a software design pattern focused on making our applications loosely coupled, extensible, and maintainable. In this tutorial, you will learn how to handle dependency injection using Dagger 2.

Introduction

When you have an object that needs or depends on another object to do its work, you have a dependency. Dependencies can be solved by letting the dependent object create the dependency or asking a factory object to make one. In the context of dependency injection, however, the dependencies are supplied to the class that needs the dependency to avoid the need for the class itself to create them. This way you create software that is loosely coupled and highly maintainable.

This tutorial uses the newest version of Dagger, Dagger 2. At the time of writing, Dagger 2 isn't officially released yet and is in pre-alpha stage. However, it is usable and stable. You can visit Dagger on GitHub to get news about the project and possible dates for the official release.

Prerequisites

You will need the latest version of Android Studio installed on your development machine, which you can download from the Android Developer website.

1. Dagger 2 API

Dagger 2 exposes a number of special annotations:

  • @Module for the classes whose methods provide dependencies
  • @Provides for the methods within @Module classes
  • @Inject to request a dependency (a constructor, a field, or a method)
  • @Component is a bridge interface between modules and injection

These are the most important annotations you need to know about to get started with dependency injection using Dagger 2. I'm going to show you how to use them in a simple Android application.

2. Dagger 2 Workflow

To implement Dagger 2 correctly, you have to follow these steps:

  1. Identify the dependent objects and its dependencies.
  2. Create a class with the @Module annotation, using the @Provides annotation for every method that returns a dependency.
  3. Request dependencies in your dependent objects using the @Inject annotation.
  4. Create an interface using the @Component annotation and add the classes with the @Module annotation created in the second step.
  5. Create an object of the @Component interface to instantiate the dependent object with its dependencies.

Dependency analysis is shifted from run time to compile time. This means that you are notified of possible problems during the development phase, unlike with other libraries, such as Guice. Before using the Dagger 2 library, you need to prepare your Android Studio installation to access the generated classes.

3. Android Studio Environment Setup

Step 1

Create a new application using Android Studio and give it a name. I've named my project TutsplusDagger.

Step 1 Type a name for the project

Step 2

Set the Minimum SDK for the project to API 10 to reach as many devices as possible.

Step 2 Select minimum SDK

Step 3

Choose the Blank layout for the activity you are creating. For this tutorial, you don't need a special layout.

Step 3 Choose the template for the project

Step 4

Name the activity MainActivity and click Finish.

Step 4 Type a name for the activity

With  the project created, you need to make a few modifications to the gradle files. Let's make those changes in the next step.

4. Configuring Gradle Setup

Step 1

We need to modify the project's build.gradle file as shown below.

Let's take a moment to see what changes we've made:

  • dependencies: In this section, I've added a plugin that is going to be useful for accessing the code generated by Dagger. If you don't, you'll see errors when referring to these new classes.
  • allprojects: This change is necessary since the libraries we're going to use are currently in pre-alpha, and this is the only place available if you want to access them using Maven. You can try to download the Dagger and Dagger Compiler libraries from Sonatype, but this tutorial is based on the Maven repositories.

Step 2

Open build.gradle in your project's app folder and modify it as shown below.

At the beginning of the file, I'm applying the new plugin. Be sure to put the new plugin (com.neenbedankt.android-apt) below or after the Android plugin. If you don't, then it's going to show errors when trying to synchronize the project with the gradle files.

In dependencies I added:

  • dagger library
  • dagger-compiler for code generation
  • javax.annotation for additional annotations required outside Dagger

After updating Dagger's configuration, you can synchronize the project with the gradle files by clicking the button at the top.

Synchronize project with grade files

At this point, you have an empty project ready to be used in your application. If you see any errors, make sure you've correctly followed the above steps. We can now proceed to implement our example project.

5. Implementing Dagger 2

Step 1: Identify Dependent Objects

For this tutorial, I'm going to work with two classes, Vehicle and Motor. Motor is the independent class and Vehicleis the dependent class. I'm going to start creating this model within a new package called model.

This is what the Motor class look like:

This class has only one attribute called rpm, which I'm going to modify through the accelerate and brake methods. And I'll check the current value using the getRpm method.

This is what the Vehicle class looks like:

In this class, you can see that I'm not creating a new object of the Motor class, even though I'm using its methods. In a real world application, this class should have more methods and attributes, but let's keep it simple for now.

Step 2: Create @Module Class

You now have to create a class with the @Module annotation. This class is going to provide the objects you will need with its dependencies satisfied. For this, you have to create a new package (just to keep it in order), name it module and add a new class inside it as follows:

As I specified in Step 1, Vehicle needsMotor to work properly. That is why you need to create two providers, one for Motor (the independent model) and another one for Vehicle (indicating its dependency).

Don't forget that every provider (or method) must have the@Provides annotation and the class must have the @Module annotation. The @Singleton annotation indicates that there will be only one instance of the object.

Step 3: Request Dependencies in Dependent Objects

Now that you have the providers for your different models, you need to request them. Just as Vehicle needs Motor, you have to add the @Inject annotation in the Vehicle constructor as follows:

You can use the @Inject annotation to request dependencies in the constructor, fields, or methods. In this case, I'm keeping the injection in the constructor.

Step 4: Connecting@Modules With @Inject

The connection between the provider of dependencies, @Module, and the classes requesting them through @Inject is made using @Component, which is an interface:

Next to the @Component annotation, you have to specify which modules are going to be used—in this case I use VehicleModule, which we created earlier. If you need to use more modules, then just add them using a comma as a separator.

Within the interface, add methods for every object you need and it will automatically give you one with all its dependencies satisfied. In this case, I only need a Vehicle object, which is why there is only one method.

Step 5: Using @Component Interface to Obtain Objects

Now that you have every connection ready, you have to obtain an instance of this interface and invoke its methods to obtain the object you need. I'm going to implement it in the onCreate method in the MainActivity as follows:

When you try to create a new object of the interface with the @Component annotation, you have to do it using the prefix Dagger_<NameOfTheComponentInterface>, in this case Dagger_VehicleComponent, and then use the builder method to call every module within.

You can see that the magic takes place on line 23. You are only asking for one object of the class Vehicle and the library is the one in charge of satisfying all the dependencies this object needs. Again you can see there is no new instantiation of any other object—everything is managed by the library.

You can now run the app and try it on your device or in an emulator. If you followed the tutorial step by step, you will see a Toast message indicating the initial value or the rpm variable.

In the attached project, you can see a custom user interface for the MainActivity class, in which you can modify the value of the rpm variable by tapping the buttons on the screen.

Conclusion

Dependency injection is a pattern that you will have to implement sooner or later in your own applications. With Dagger 2, you have an easy-to-use library to implement it. I hope you found this tutorial useful, and don't forget to share it if you liked it.

2015-03-11T15:45:11.000Z2015-03-11T15:45:11.000ZKerry Perez Huanca

Windows Phone 8 Succinctly: Data Access—Storage

$
0
0

Local Storage

The Internet plays an important role in mobile applications. Most Windows Phone applications available in the Store make use of the network connection offered by every device. However, relying only on the network connection can be a mistake; users can find themselves in situations where no connection is available. In addition, data plans are often limited, so the fewer network operations we do, the better the user experience is.

Windows Phone offers a special way to store local data called isolated storage. It works like a regular file system, so you can create folders and files as on a computer hard drive. The difference is that the storage is isolated—only your applications can use it. No other applications can access your storage, and users are not able to see it when they connect their phone to the computer. Moreover, as a security measure, the isolated storage is the only storage that the application can use. You’re not allowed to access the operating system folders or write data in the application’s folder.

Local storage is one of the features which offers duplicated APIs—the old Silverlight ones based on the IsolatedStorageFile class and the new Windows Runtime ones based on the LocalFolder class. As mentioned in the beginning of the series, we’re going to focus on the Windows Runtime APIs.

Working With Folders

The base class that identifies a folder in the local storage is called StorageFolder. Even the root of the storage (which can be accessed using the ApplicationData.Current.LocalStorage class that is part of the Windows.Storage namespace) is a StorageFolder object.

This class exposes different asynchronous methods to interact with the current folder, such as:

  • CreateFolderAsync() to create a new folder in the current path.
  • GetFolderAsync() to get a reference to a subfolder of the current path.
  • GetFoldersAsync() to get the list of folders available in the current path.
  • DeleteAsync() to delete the current folder.
  • RenameAsync() to rename a folder.

In the following sample, you can see how to create a folder in the local storage’s root:

Unfortunately, the APIs don’t have a method to check if a folder already exists. The simplest solution is to try to open the folder using the GetFolderAsync() method and intercept the FileNotFoundException error that is raised if the folder doesn’t exist, as shown in the following sample:

Working With Files

Files, instead, are identified by the StorageFile class, which similarly offers methods to interact with files:

  • DeleteAsync() to delete a file.
  • RenameAsync() to rename a file.
  • CopyAsync() to copy a file from one location to another.
  • MoveAsync() to move a file from one location to another.

The starting point to manipulate a file is the StorageFolder class we’ve previously discussed, since it offers methods to open an existing file (GetFileAsync()) or to create a new one in the current folder (CreateFileAsync()).

Let’s examine the two most common operations: writing content to a file and reading content from a file.

How to Create a File

As already mentioned, the first step to create a file is to use the CreateFile() method on a StorageFolder object. The following sample shows how to create a new file called file.txt in the local storage’s root:

You can also pass the optional parameter CreationCollisionOption to the method to define the behavior to use in case a file with the same name already exists. In the previous sample, the ReplaceExisting value is used to overwrite the existing file.

Now that you have a file reference thanks to the StorageFile object, you are able to work with it using the OpenAsync() method. This method returns the file stream, which you can use to write and read content.

The following sample shows how to write text inside the file:

The key is the DataWriter class, which is a Windows Runtime class that can be used to easily write data to a file. We simply have to create a new DataWriter object, passing as a parameter the output stream of the file we get using the GetOuputStreamAt() method on the stream returned by the OpenAsync() method.

The DataWriter class offers many methods to write different data types, like WriteDouble() for decimal numbers, WriteDateTime() for dates, and WriteBytes() for binary data. In the sample we write text using the WriteString() method, and then we call the StoreAsync() and FlushAsync() methods to finalize the writing operation.

Note: The using statement can be used with classes that support the IDisposable interface. They are typically objects that lock a resource until the operation is finished, like in the previous sample. Until the writing operation is finished, no other methods can access the file. With the using statement, we make sure that the lock is released when the operation is completed.

How to Read a File

The operation to read a file is not very different from the writing one. In this case, we also need to get the file stream using the OpenFile() method. The difference is that, instead of using the DataWriter class, we’re going to use the DataReader class, which does the opposite operation. Look at the following sample code:

In this case, instead of the CreateFileAsync() method, we use the GetFileAsync() method, which can be used to get a reference to an already existing file. Then, we start the reading procedure using the DataReader class, this time using the input stream that we get using the GetInputStreamAt() method.

Like the DataWriter class, DataReader also offers many methods to read different data types, like ReadDouble(), ReadDateTime(), and ReadBytes(). In this case, we read the text we’ve previously written by using the ReadString() method, which requires the size of the file as its parameter.

A Special Folder: InstalledLocation

The local storage is the only storage we can use to write our application’s data, but in some cases, we may need to include in our project some existing files that need to be processed by the application.

The Windows Runtime offers an API to provide access to the folder where the application is installed and where all the files that are part of your Visual Studio project are copied. It’s called Package.Current.InstalledLocation, and it’s part of the Windows.ApplicationModel namespace.

The InstalledLocation’s type is StorageFolder, like the folders in local storage, so you can use the same methods to work with files and folders. Keep in mind that you won’t be able to write data, but only read it.

In the following sample, we copy a file from the application’s folder to the local storage so that we gain write access.

Note: During development you may notice that you’ll be able to execute write operations in the application’s folder. Don’t count on it—during the certification process, the app is locked, so when the app is distributed on the Windows Phone Store, the write access is revoked and you’ll start getting exceptions.

Manage Settings

One common scenario in mobile development is the need to store settings. Many applications offer a Settings page where users can customize different options.

To allow developers to quickly accomplish this task, the SDK includes a class called IsolatedStorageSettings, which offers a dictionary called ApplicationSettings that you can use to store settings.

Note: The IsolatedStorageSettings class is part of the old storage APIs; the Windows Runtime offers a new API to manage settings but, unfortunately, it isn’t available in Windows Phone.

Using the ApplicationSettings property is very simple: its type is Dictionary<string, object> and it can be used to store any object.

In the following sample, you can see two event handlers: the first one saves an object in the settings, while the second one retrieves it.

The only thing to highlight is the Save() method, which you need to call every time you want to persist the changes you’ve made. Except for this, it works like a regular Dictionary collection.

Note: Under the hood, settings are stored in an XML file. The API automatically takes care of serializing and deserializing the object you save. We’ll talk more about serialization later in this article.

Debugging the Local Storage

A common requirement for a developer working with local storage is the ability to see which files and folders are actually stored. Since the storage is isolated, developers can’t simply connect the phone to a computer and explore it.

The best way to view an application’s local storage is by using a third-party tool available on CodePlex called Windows Phone Power Tools, which offers a visual interface for exploring an application’s local storage.

The tool is easy to use. After you’ve installed it, you’ll be able to connect to a device or to one of the available emulators. Then, in the Isolated Storage section, you’ll see a list of all the applications that have been side-loaded from Visual Studio. Each one will be identified by its application ID (which is a GUID). Like a regular file explorer, you can expand the tree structure and analyze the storage’s content. You’ll be able to save files from the device to your PC, copy files from your PC to the application storage, and even delete items.

Local Storage of a Windows Phone Application

Storing Techniques

In the previous section, we discussed the basic APIs available to store files and folders in your application. In this section, we’ll go deeper to see the best ways to store your application’s data, so that it can be maintained across different applications.

Serialization and Deserialization

Serialization is the simplest way to store an application’s data in the local storage. It’s the process that converts complex objects into plain text so that they can be stored in a text file, using XML or JSON as output. Deserialization is the opposite process; the plain text is converted back into objects so that they can be used by the application.

In a Windows Phone application that uses these techniques, serialization is typically applied every time the application’s data is changed (when a new item is added, edited, or removed) to minimize the risk of losing data if something happens, like an unexpected crash or a suspension. Deserialization, instead, is usually applied when the application starts for the first time.

Serialization is very simple to use, but its usage should be limited to applications that work with small amounts of data, since everything is kept in memory during the execution. Moreover, it best suits scenarios where the data to track is simple. If you have to deal with many relationships, databases are probably a better solution (we’ll talk more about this later in the article).

In the following samples, we’re going to use the same Person class we used earlier in this series.

We assume that you will have a collection of Person objects, which represents your local data:

Serialization

To serialize our application’s data we’re going to use the local storage APIs we learned about in the previous section. We’ll use the CreateFile() method again, as shown in the following sample:

The DataContractSerializer class (which is part of the System.Runtime.Serialization namespace) takes care of managing the serialization process. When we create a new instance, we need to specify which data type we’re going to serialize (in the previous sample, it’s List<Person>). Next, we create a new file in the local storage and get the stream needed to write the data. The serialization operation is made by calling the WriteObject() method of the DataContractSerializer class, which requires as parameters the stream location in which to write the data and the object to serialize. In this example, it’s the collection of Person objects we’ve previously defined.

If you take a look at the storage content using the Windows Phone Power Tools, you’ll find a people.xml file, which contains an XML representation of your data:

Tip: The DataContractSerializer class uses XML as its output format. If you want to use JSON instead, you’ll have to use the DataContractJsonSerializer class, which works in the same way.

Deserialization

The deserialization process is very similar and involves, again, the storage APIs to read the file’s content and the DataContractSerializer class. The following sample shows how to deserialize the data we serialized in the previous section:

The only differences are:

  • We get a stream to read by using the AsStreamForRead() method.
  • We use the ReadObject() method of the DataContractSerializer class to deserialize the file’s content, which takes the file stream as its input parameter. It’s important to note that the method always returns a generic object, so you’ll always have to cast it to your real data type (in the sample, we cast it as List<Person>).

Using Databases: SQL CE

When you develop complex applications, you probably have to deal with complex data. Databases are a good solution to manage this scenario because they support relationships, and because the entire dataset is not kept in memory, only the needed items are.

SQL CE is the database solution that was introduced in Windows Phone 7.5. It’s a stand-alone database, which means that data is stored in a single file in the storage without needing a DBMS to manage all the operations.

Windows Phone uses SQL CE 3.5 (the latest release at this time is 4.0, but it is not supported) and doesn’t support SQL query execution. Every operation is made using LINQ to SQL, which is one of the first of Microsoft’s ORM solutions.

Note: ORM (Object-Relation Mapping) solutions are libraries that are able to automatically translate object operations (insert, edit, remove) into database operations. This way, you can keep working on your project using an object-oriented approach. ORM will take care of writing the required SQL queries to store your data in the database.

The approach used by SQL CE on Windows Phone is called code first. The database is created the first time the data is needed, according to the entities definition that you’re going to store in tables. Another solution is to include an already existing SQL CE file in your Visual Studio project. In this case, you’ll only be able to work with it in read-only mode.

How to Define the Database

The first step is to create the entities that you’ll need to store in your database. Each entity will be mapped to a specific table.

Entity definition is made using attributes, which are part of the System.Data.Linq.Mapping namespace. Each property is decorated with an attribute, which will be used to translate it into a column. In the following sample we adapt the familiar Person class to be stored in a table:

The entire entity is marked with the Table attribute, while every property is marked with the Column attribute. Attributes can be customized with some properties, like:

  • IsPrimaryKey to apply to columns that are part of the primary key.
  • IsDbGenerated in case the column’s value needs to be automatically generated every time a new row is inserted (for example, an automatically incremented number).
  • Name if you want to assign to the column a different name than the property.
  • DbType to customize the column’s type. By default, the column’s type is automatically set by the property’s type.

Working With the Database: The DataContext

DataContext is a special class that acts as an intermediary between the database and your application. It exposes all the methods needed to perform the most common operations, like insert, update, and delete.

The DataContext class contains the connection string’s definition (which is the path where the database is stored) and all the tables that are included in the database. In the following sample, you can see a DataContext definition that includes the Person table we’ve previously defined:

A separate class of your project inherits from the DataContext class. It will force you to implement a public constructor that supports a connection string as its input parameter. There are two connection string types, based on the following prefixes:

  • isostore:/ means that the file is stored in the local storage. In the previous sample, the database’s file name is Persons.sdf and it’s stored in the storage’s root.
  • appdata:/ means that the file is stored in the Visual Studio project instead. In this case, you’re forced to set the File Mode attribute to Read Only.

Eventually, you can also encrypt the database by adding a Password attribute to the connection string:

Creating the Database

As soon as the data is needed, you’ll need to create the database if it doesn’t exist yet. For this purpose, the DataContext class exposes two methods:

  • DatabaseExists() returns whether the database already exists.
  • CreateDatabase() effectively creates the database in the storage.

In the following sample, you can see a typical database initialization that is executed every time the application starts:

Working With the Data

All the operations are made using the Table<T> object that we’ve declared in the DataContext definition. It supports standard LINQ operations, so you can query the data using methods like Where(), FirstOrDefault(), Select(), and OrderBy().

In the following sample, you can see how we retrieve all the Person objects in the table whose name is Matteo:

The returned result can be used not only for display purposes, but also for editing. To update the item in the database, you can change the values of the returned object by calling the SubmitChanges() method exposed by the DataContext class.

To add new items to the table, the Table<T> class offers two methods: InsertOnSubmit() and InsertAllOnSubmit(). The first method can be used to insert a single object, while the second one adds multiple items in one operation (in fact, it accepts a collection as a parameter).

Please note again the SubmitChanges() method: it’s important to call it every time you modify the table (by adding a new item or editing or deleting an already existing one), otherwise changes won’t be saved.

In a similar way, you can delete items by using the DeleteOnSubmit() and DeleteAllOnSubmit() methods. In the following sample, we delete all persons with the name Matteo:

Relationships

In the previous sections, we’ve talked about data that is stored in a single table. Now it’s time to introduce relationships, which are a way to connect two or more tables. As an example, we’ll add a new Order entity to our database, which we’ll use to save the orders made by users stored in the Person table.

With LINQ to SQL we’ll be able to:

  • Add a Person property to the Order entity that will store a reference to the user who made the order.
  • Add an Orders collection to the Person entity that will contain all the orders made by the user.

This is accomplished by using a foreign key, which is a property declared in the Order entity that will hold the primary key value of the user who made the order. 

Here is how the Order class looks:

There are two key properties in the class definition:

  • PersonId is the foreign key, which simply holds the person’s ID.
  • Person is a real Person object that, thanks to the Association attribute, is able to hold a reference to the user who made the order. The property’s setter contains some logic to manage whether you’re adding a new value or removing an already existing one.

Of course, we have to also change the Person class definition in order to manage the relationships:

Also in this class, we’ve defined a new property called Orders, whose type is EntitySet<T>, where T is the type of the other table involved in the relationship. Thanks to the Association attribute, we are be able to access all the orders made by a user simply by querying the Orders collection.

In the following samples, you can see two common operations in which a relationship is involved: creation and selection.

Since Person is a property of the Order class, it’s enough to create a new order and set the object that represents the user who made the order as a value of the Person property.

In the same way, when we get an order we are able to get the user’s details simply by querying the Person property. In the previous sample, we display the name of the user who made the order.

Updating the Schema

A common scenario when you’re planning to release an application update is that you’ve changed the database schema by adding a new table or new column, for example.

SQL CE in Windows Phone offers a specific class to satisfy this requirement, called DatabaseSchemaUpdater, which offers some methods to update an already existing database’s schema.

Note: The DatabaseSchemaUpdater’s purpose is just to update the schema of an already existing database. You still need to update your entities and DataContext definition to reflect the new changes.

The key property offered by the DatabaseSchemaUpdater class is DatabaseSchemaVersion, which is used to track the current schema’s version. It’s important to properly set it every time we apply an update because we’re going to use it when the database is created or updated to recognize whether we’re using the latest version.

After you’ve modified your entities or the DataContext definition in your project, you can use the following methods:

  • AddTable<T>() if you’ve added a new table (of type T).
  • AddColumn<T>() if you’ve added a new column to a table (of type T).
  • AddAssociation<T>() if you’ve added a new relationship to a table (of type T).

The following sample code is executed when the application starts and needs to take care of the schema update process:

We’re assuming that the current database’s schema version is 2. In case the database doesn’t exist, we simply create it and, using the DatabaseSchemaUpdater class, we update the DatabaseSchemaVersion property. This way, the next time the data will be needed, the update operation won’t be executed since we’re already working with the latest version.

Instead, if the database already exists, we check the version number. If it’s an older version, we update the current schema. In the previous sample, we’ve added a new column to the Person table, called BirthDate (which is the parameter requested by the AddColumn<T>() method). Also in this case we need to remember to properly set the DatabaseSchemaVersion property to avoid further executions of the update operation.

In both cases, we need to apply the described changes by calling the Execute() method.

SQL Server Compact Toolbox: An Easier Way to Work With SQL CE

Erik Ej, a Microsoft MVP, has developed a powerful Visual Studio tool called SQL Server Compact Toolbox that can be very helpful for dealing with SQL CE and Windows Phone applications.

Two versions of the tool are available:

  • As an extension that’s integrated into commercial versions of Visual Studio.
  • As a stand-alone tool for Visual Studio Express since it does not support extensions.

The following are some of the features supported by the tool:

  • Automatically create entities and a DataContext class starting from an already existing SQL CE database.
  • The generated DataContext is able to copy a database from your Visual Studio project to your application’s local storage. This way, you can start with a prepopulated database and, at the same time, have write access.
  • The generated DataContext supports logging in the Visual Studio Output Window so you can see the SQL queries generated by LINQ to SQL.

Using Databases: SQLite

SQLite, from a conceptual point of view, is a similar solution to SQL CE: it’s a stand-alone database solution, where data is stored in a single file without a DBMS requirement.

The pros of using SQLite are: 

  • It offers better performance than SQL CE, especially with large amounts of data.
  • It is open source and cross-platform; you’ll find a SQLite implementation for Windows 8, Android, iOS, web apps, etc.

SQLite support has been introduced only in Windows Phone 8 due to the new native code support feature (since the SQLite engine is written in native code), and it’s available as a Visual Studio extension that you can download from the Visual Studio website.

After you’ve installed it, you’ll find the SQLite for Windows Phone runtime available in the Add reference window, in the Windows Phone Extension section. Be careful; this runtime is just the SQLite engine, which is written in native code. If you need to use a SQLite database in a C# application, you’ll need a third-party library that is able to execute the appropriate native calls for you.

In actuality, there are two available SQLite libraries: sqlite-net and SQLite Wrapper for Windows Phone. Unfortunately, neither of them is as powerful and flexible as the LINQ to SQL library that is available for SQL CE.

Let’s take a brief look at them. We won’t dig too deeply. Since they’re in constant development, things can change very quickly.

Sqlite-net

Sqlite-net is a third-party library. The original version for Windows Store apps is developed by Frank A. Krueger, while the Windows Phone 8 port is developed by Peter Huene.

The Windows Phone version is available on GitHub. Its configuration procedure is a bit tricky and changes from time to time, so be sure to follow the directions provided by the developer on the project’s home page.

Sqlite-net offers a LINQ approach to use the database that is similar to the code-first one offered by LINQ to SQL with SQL CE.

For example, in sqlite-net, tables are mapped with your project’s entities. The difference is that, this time, attributes are not required since every property will be automatically translated into a column. Attributes are needed only if you need to customize the conversion process, as in the following sample:

Surname doesn’t have any attribute, so it will be automatically converted into a varchar column. Instead, we set Id as a primary key with an auto increment value, while we specify that Name can have a maximum length of 50 characters.

All the basic operations with the database are accomplished using the SQLiteAsyncConnection class, which exposes asynchronous methods to create tables, query the data, delete items, etc. It requires as an input parameter the local storage path where the database will be saved.

As with SQL CE and LINQ to SQL, we need to create the database before using it. This is done by calling the CreateTableAsync<T>() method for every table we need to create, where T is the table’s type. In the following sample, we create a table to store the Person entity:

We don’t have a method to verify whether the table already exists since it’s not needed; if the table we’re creating already exists, the CreateTableAsync<T>() method simply won’t do anything.

In a similar way to LINQ to SQL, queries are performed using the Table<T> object. The only difference is that all the LINQ methods are asynchronous.

In the previous sample, we retrieve all the Person objects whose name is Matteo.

Insert, update, and delete operations are instead directly executed using the SQLiteAsyncConnection object, which offers the InsertAsync(), UpdateAsync(), and DeleteAsync() methods. It is not required to specify the object’s type; sqlite-net will automatically detect it and execute the operation on the proper table. In the following sample, you can see how a new record is added to a table:

Sqlite-net is the SQLite library that offers the easiest approach, but it has many limitations. For example, foreign keys are not supported, so it’s not possible to easily manage relationships.

SQLite Wrapper for Windows Phone

SQLite Wrapper for Windows Phone has been developed directly by Microsoft team members (notably Peter Torr and Andy Wigley) and offers a totally different approach than sqlite-net. It doesn’t support LINQ, just plain SQL query statements.

The advantage is that you have total control and freedom, since every SQL feature is supported: indexes, relationships, etc. The downside is that writing SQL queries for every operation takes more time, and it’s not as easy and intuitive as using LINQ.

To learn how to configure the wrapper in your project, follow the instructions posted on the CodePlex project page. You’ll have to download the project’s source code and add the correct wrapper version to your solution—there are two separate libraries, one for Windows Phone 8 and one for Windows Store apps.

The key class is called Database, which takes care of initializing the database and offers all the methods needed to perform the queries. As a parameter, you need to set the local storage path to save the database. If the path doesn’t exist, it will be automatically created. Then, you need to open the connection using the OpenAsync() method. Now you are ready to perform operations.

There are two ways to execute a query based on the value it returns.

If the query doesn’t return a value—for example, a table creation—you can use the ExecuteStatementAsync() method as shown in the following sample:

The previous method simply executes the query against the opened database. In the sample, we create a People table with two fields, Name and Surname.

The query, instead, can contain some dynamic parameters or return some values. In this case, we need to introduce a new class called Statement as demonstrated in the following sample:

The Statement class identifies a query, but it allows additional customization to be performed with it. In the sample, we use it to assign a dynamic value to the Name and Surname parameters. We set the placeholder using the @ prefix (@name and @surname), and then we assign them a value using the BindTextParameterWithName() method, passing the parameter’s name and the value.

BindTextParameterWithName() isn’t the only available method, but it’s specifically for string parameters. There are other methods based on the parameter’s type, such as BindIntParameterWithName() for numbers.

To execute the query, we use the StepAsync() method. Its purpose isn’t just to execute the query, but also to iterate the resulting rows.

In the following sample, we can see how this method can be used to manage the results of a SELECT query:

The StepAsync() method is included inside a while statement. At every loop iteration, we’ll get the reference to the next row returned by the query, starting from the first one. After we’ve iterated all the rows, the application will quit the while loop.

When we have a row’s reference, we can access its values by using the column index and the Get() method. We have a Get() variant for every data type, like GetText(), GetInt(), etc.

Another way is to access the columns using the Columns collection with the column name as the index. In this case, you first have to call the EnableColumnsProperty() method, as shown in the following sample:

Keep in mind that this approach is slower than using the column’s index.

Conclusion

This article delivered more key concepts that every Windows Phone developer should be familiar with. Managing local data is important, and in this article we’ve discussed the following approaches:

  • Correctly using files and folders in the isolated storage thanks to the Windows Runtime APIs.
  • Easily managing our application’s settings by using the IsolatedStorageSettings class.
  • Storing our application’s data using serialization and deserialization in simple app scenarios.
  • In case of more complex applications, we’ve seen how we can better organize our data using databases. We analyzed two available solutions: SQL CE and SQLite. They both offer a stand-alone database platform. SQL CE is exclusive to Windows Phone, but it is more powerful and easier to use; SQLite is open source and cross-platform, but you have to rely on third-party libraries which aren’t as powerful as LINQ to SQL for SQL CE.

This tutorial represents a chapter from Windows Phone 8 Succinctly, a free eBook from the team at Syncfusion.

2015-03-12T08:30:46.000Z2015-03-12T08:30:46.000ZMatteo Pagani

Windows Phone 8 Succinctly: Data Access—Storage

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

Local Storage

The Internet plays an important role in mobile applications. Most Windows Phone applications available in the Store make use of the network connection offered by every device. However, relying only on the network connection can be a mistake; users can find themselves in situations where no connection is available. In addition, data plans are often limited, so the fewer network operations we do, the better the user experience is.

Windows Phone offers a special way to store local data called isolated storage. It works like a regular file system, so you can create folders and files as on a computer hard drive. The difference is that the storage is isolated—only your applications can use it. No other applications can access your storage, and users are not able to see it when they connect their phone to the computer. Moreover, as a security measure, the isolated storage is the only storage that the application can use. You’re not allowed to access the operating system folders or write data in the application’s folder.

Local storage is one of the features which offers duplicated APIs—the old Silverlight ones based on the IsolatedStorageFile class and the new Windows Runtime ones based on the LocalFolder class. As mentioned in the beginning of the series, we’re going to focus on the Windows Runtime APIs.

Working With Folders

The base class that identifies a folder in the local storage is called StorageFolder. Even the root of the storage (which can be accessed using the ApplicationData.Current.LocalStorage class that is part of the Windows.Storage namespace) is a StorageFolder object.

This class exposes different asynchronous methods to interact with the current folder, such as:

  • CreateFolderAsync() to create a new folder in the current path.
  • GetFolderAsync() to get a reference to a subfolder of the current path.
  • GetFoldersAsync() to get the list of folders available in the current path.
  • DeleteAsync() to delete the current folder.
  • RenameAsync() to rename a folder.

In the following sample, you can see how to create a folder in the local storage’s root:

Unfortunately, the APIs don’t have a method to check if a folder already exists. The simplest solution is to try to open the folder using the GetFolderAsync() method and intercept the FileNotFoundException error that is raised if the folder doesn’t exist, as shown in the following sample:

Working With Files

Files, instead, are identified by the StorageFile class, which similarly offers methods to interact with files:

  • DeleteAsync() to delete a file.
  • RenameAsync() to rename a file.
  • CopyAsync() to copy a file from one location to another.
  • MoveAsync() to move a file from one location to another.

The starting point to manipulate a file is the StorageFolder class we’ve previously discussed, since it offers methods to open an existing file (GetFileAsync()) or to create a new one in the current folder (CreateFileAsync()).

Let’s examine the two most common operations: writing content to a file and reading content from a file.

How to Create a File

As already mentioned, the first step to create a file is to use the CreateFile() method on a StorageFolder object. The following sample shows how to create a new file called file.txt in the local storage’s root:

You can also pass the optional parameter CreationCollisionOption to the method to define the behavior to use in case a file with the same name already exists. In the previous sample, the ReplaceExisting value is used to overwrite the existing file.

Now that you have a file reference thanks to the StorageFile object, you are able to work with it using the OpenAsync() method. This method returns the file stream, which you can use to write and read content.

The following sample shows how to write text inside the file:

The key is the DataWriter class, which is a Windows Runtime class that can be used to easily write data to a file. We simply have to create a new DataWriter object, passing as a parameter the output stream of the file we get using the GetOuputStreamAt() method on the stream returned by the OpenAsync() method.

The DataWriter class offers many methods to write different data types, like WriteDouble() for decimal numbers, WriteDateTime() for dates, and WriteBytes() for binary data. In the sample we write text using the WriteString() method, and then we call the StoreAsync() and FlushAsync() methods to finalize the writing operation.

Note: The using statement can be used with classes that support the IDisposable interface. They are typically objects that lock a resource until the operation is finished, like in the previous sample. Until the writing operation is finished, no other methods can access the file. With the using statement, we make sure that the lock is released when the operation is completed.

How to Read a File

The operation to read a file is not very different from the writing one. In this case, we also need to get the file stream using the OpenFile() method. The difference is that, instead of using the DataWriter class, we’re going to use the DataReader class, which does the opposite operation. Look at the following sample code:

In this case, instead of the CreateFileAsync() method, we use the GetFileAsync() method, which can be used to get a reference to an already existing file. Then, we start the reading procedure using the DataReader class, this time using the input stream that we get using the GetInputStreamAt() method.

Like the DataWriter class, DataReader also offers many methods to read different data types, like ReadDouble(), ReadDateTime(), and ReadBytes(). In this case, we read the text we’ve previously written by using the ReadString() method, which requires the size of the file as its parameter.

A Special Folder: InstalledLocation

The local storage is the only storage we can use to write our application’s data, but in some cases, we may need to include in our project some existing files that need to be processed by the application.

The Windows Runtime offers an API to provide access to the folder where the application is installed and where all the files that are part of your Visual Studio project are copied. It’s called Package.Current.InstalledLocation, and it’s part of the Windows.ApplicationModel namespace.

The InstalledLocation’s type is StorageFolder, like the folders in local storage, so you can use the same methods to work with files and folders. Keep in mind that you won’t be able to write data, but only read it.

In the following sample, we copy a file from the application’s folder to the local storage so that we gain write access.

Note: During development you may notice that you’ll be able to execute write operations in the application’s folder. Don’t count on it—during the certification process, the app is locked, so when the app is distributed on the Windows Phone Store, the write access is revoked and you’ll start getting exceptions.

Manage Settings

One common scenario in mobile development is the need to store settings. Many applications offer a Settings page where users can customize different options.

To allow developers to quickly accomplish this task, the SDK includes a class called IsolatedStorageSettings, which offers a dictionary called ApplicationSettings that you can use to store settings.

Note: The IsolatedStorageSettings class is part of the old storage APIs; the Windows Runtime offers a new API to manage settings but, unfortunately, it isn’t available in Windows Phone.

Using the ApplicationSettings property is very simple: its type is Dictionary<string, object> and it can be used to store any object.

In the following sample, you can see two event handlers: the first one saves an object in the settings, while the second one retrieves it.

The only thing to highlight is the Save() method, which you need to call every time you want to persist the changes you’ve made. Except for this, it works like a regular Dictionary collection.

Note: Under the hood, settings are stored in an XML file. The API automatically takes care of serializing and deserializing the object you save. We’ll talk more about serialization later in this article.

Debugging the Local Storage

A common requirement for a developer working with local storage is the ability to see which files and folders are actually stored. Since the storage is isolated, developers can’t simply connect the phone to a computer and explore it.

The best way to view an application’s local storage is by using a third-party tool available on CodePlex called Windows Phone Power Tools, which offers a visual interface for exploring an application’s local storage.

The tool is easy to use. After you’ve installed it, you’ll be able to connect to a device or to one of the available emulators. Then, in the Isolated Storage section, you’ll see a list of all the applications that have been side-loaded from Visual Studio. Each one will be identified by its application ID (which is a GUID). Like a regular file explorer, you can expand the tree structure and analyze the storage’s content. You’ll be able to save files from the device to your PC, copy files from your PC to the application storage, and even delete items.

Local Storage of a Windows Phone Application

Storing Techniques

In the previous section, we discussed the basic APIs available to store files and folders in your application. In this section, we’ll go deeper to see the best ways to store your application’s data, so that it can be maintained across different applications.

Serialization and Deserialization

Serialization is the simplest way to store an application’s data in the local storage. It’s the process that converts complex objects into plain text so that they can be stored in a text file, using XML or JSON as output. Deserialization is the opposite process; the plain text is converted back into objects so that they can be used by the application.

In a Windows Phone application that uses these techniques, serialization is typically applied every time the application’s data is changed (when a new item is added, edited, or removed) to minimize the risk of losing data if something happens, like an unexpected crash or a suspension. Deserialization, instead, is usually applied when the application starts for the first time.

Serialization is very simple to use, but its usage should be limited to applications that work with small amounts of data, since everything is kept in memory during the execution. Moreover, it best suits scenarios where the data to track is simple. If you have to deal with many relationships, databases are probably a better solution (we’ll talk more about this later in the article).

In the following samples, we’re going to use the same Person class we used earlier in this series.

We assume that you will have a collection of Person objects, which represents your local data:

Serialization

To serialize our application’s data we’re going to use the local storage APIs we learned about in the previous section. We’ll use the CreateFile() method again, as shown in the following sample:

The DataContractSerializer class (which is part of the System.Runtime.Serialization namespace) takes care of managing the serialization process. When we create a new instance, we need to specify which data type we’re going to serialize (in the previous sample, it’s List<Person>). Next, we create a new file in the local storage and get the stream needed to write the data. The serialization operation is made by calling the WriteObject() method of the DataContractSerializer class, which requires as parameters the stream location in which to write the data and the object to serialize. In this example, it’s the collection of Person objects we’ve previously defined.

If you take a look at the storage content using the Windows Phone Power Tools, you’ll find a people.xml file, which contains an XML representation of your data:

Tip: The DataContractSerializer class uses XML as its output format. If you want to use JSON instead, you’ll have to use the DataContractJsonSerializer class, which works in the same way.

Deserialization

The deserialization process is very similar and involves, again, the storage APIs to read the file’s content and the DataContractSerializer class. The following sample shows how to deserialize the data we serialized in the previous section:

The only differences are:

  • We get a stream to read by using the AsStreamForRead() method.
  • We use the ReadObject() method of the DataContractSerializer class to deserialize the file’s content, which takes the file stream as its input parameter. It’s important to note that the method always returns a generic object, so you’ll always have to cast it to your real data type (in the sample, we cast it as List<Person>).

Using Databases: SQL CE

When you develop complex applications, you probably have to deal with complex data. Databases are a good solution to manage this scenario because they support relationships, and because the entire dataset is not kept in memory, only the needed items are.

SQL CE is the database solution that was introduced in Windows Phone 7.5. It’s a stand-alone database, which means that data is stored in a single file in the storage without needing a DBMS to manage all the operations.

Windows Phone uses SQL CE 3.5 (the latest release at this time is 4.0, but it is not supported) and doesn’t support SQL query execution. Every operation is made using LINQ to SQL, which is one of the first of Microsoft’s ORM solutions.

Note: ORM (Object-Relation Mapping) solutions are libraries that are able to automatically translate object operations (insert, edit, remove) into database operations. This way, you can keep working on your project using an object-oriented approach. ORM will take care of writing the required SQL queries to store your data in the database.

The approach used by SQL CE on Windows Phone is called code first. The database is created the first time the data is needed, according to the entities definition that you’re going to store in tables. Another solution is to include an already existing SQL CE file in your Visual Studio project. In this case, you’ll only be able to work with it in read-only mode.

How to Define the Database

The first step is to create the entities that you’ll need to store in your database. Each entity will be mapped to a specific table.

Entity definition is made using attributes, which are part of the System.Data.Linq.Mapping namespace. Each property is decorated with an attribute, which will be used to translate it into a column. In the following sample we adapt the familiar Person class to be stored in a table:

The entire entity is marked with the Table attribute, while every property is marked with the Column attribute. Attributes can be customized with some properties, like:

  • IsPrimaryKey to apply to columns that are part of the primary key.
  • IsDbGenerated in case the column’s value needs to be automatically generated every time a new row is inserted (for example, an automatically incremented number).
  • Name if you want to assign to the column a different name than the property.
  • DbType to customize the column’s type. By default, the column’s type is automatically set by the property’s type.

Working With the Database: The DataContext

DataContext is a special class that acts as an intermediary between the database and your application. It exposes all the methods needed to perform the most common operations, like insert, update, and delete.

The DataContext class contains the connection string’s definition (which is the path where the database is stored) and all the tables that are included in the database. In the following sample, you can see a DataContext definition that includes the Person table we’ve previously defined:

A separate class of your project inherits from the DataContext class. It will force you to implement a public constructor that supports a connection string as its input parameter. There are two connection string types, based on the following prefixes:

  • isostore:/ means that the file is stored in the local storage. In the previous sample, the database’s file name is Persons.sdf and it’s stored in the storage’s root.
  • appdata:/ means that the file is stored in the Visual Studio project instead. In this case, you’re forced to set the File Mode attribute to Read Only.

Eventually, you can also encrypt the database by adding a Password attribute to the connection string:

Creating the Database

As soon as the data is needed, you’ll need to create the database if it doesn’t exist yet. For this purpose, the DataContext class exposes two methods:

  • DatabaseExists() returns whether the database already exists.
  • CreateDatabase() effectively creates the database in the storage.

In the following sample, you can see a typical database initialization that is executed every time the application starts:

Working With the Data

All the operations are made using the Table<T> object that we’ve declared in the DataContext definition. It supports standard LINQ operations, so you can query the data using methods like Where(), FirstOrDefault(), Select(), and OrderBy().

In the following sample, you can see how we retrieve all the Person objects in the table whose name is Matteo:

The returned result can be used not only for display purposes, but also for editing. To update the item in the database, you can change the values of the returned object by calling the SubmitChanges() method exposed by the DataContext class.

To add new items to the table, the Table<T> class offers two methods: InsertOnSubmit() and InsertAllOnSubmit(). The first method can be used to insert a single object, while the second one adds multiple items in one operation (in fact, it accepts a collection as a parameter).

Please note again the SubmitChanges() method: it’s important to call it every time you modify the table (by adding a new item or editing or deleting an already existing one), otherwise changes won’t be saved.

In a similar way, you can delete items by using the DeleteOnSubmit() and DeleteAllOnSubmit() methods. In the following sample, we delete all persons with the name Matteo:

Relationships

In the previous sections, we’ve talked about data that is stored in a single table. Now it’s time to introduce relationships, which are a way to connect two or more tables. As an example, we’ll add a new Order entity to our database, which we’ll use to save the orders made by users stored in the Person table.

With LINQ to SQL we’ll be able to:

  • Add a Person property to the Order entity that will store a reference to the user who made the order.
  • Add an Orders collection to the Person entity that will contain all the orders made by the user.

This is accomplished by using a foreign key, which is a property declared in the Order entity that will hold the primary key value of the user who made the order. 

Here is how the Order class looks:

There are two key properties in the class definition:

  • PersonId is the foreign key, which simply holds the person’s ID.
  • Person is a real Person object that, thanks to the Association attribute, is able to hold a reference to the user who made the order. The property’s setter contains some logic to manage whether you’re adding a new value or removing an already existing one.

Of course, we have to also change the Person class definition in order to manage the relationships:

Also in this class, we’ve defined a new property called Orders, whose type is EntitySet<T>, where T is the type of the other table involved in the relationship. Thanks to the Association attribute, we are be able to access all the orders made by a user simply by querying the Orders collection.

In the following samples, you can see two common operations in which a relationship is involved: creation and selection.

Since Person is a property of the Order class, it’s enough to create a new order and set the object that represents the user who made the order as a value of the Person property.

In the same way, when we get an order we are able to get the user’s details simply by querying the Person property. In the previous sample, we display the name of the user who made the order.

Updating the Schema

A common scenario when you’re planning to release an application update is that you’ve changed the database schema by adding a new table or new column, for example.

SQL CE in Windows Phone offers a specific class to satisfy this requirement, called DatabaseSchemaUpdater, which offers some methods to update an already existing database’s schema.

Note: The DatabaseSchemaUpdater’s purpose is just to update the schema of an already existing database. You still need to update your entities and DataContext definition to reflect the new changes.

The key property offered by the DatabaseSchemaUpdater class is DatabaseSchemaVersion, which is used to track the current schema’s version. It’s important to properly set it every time we apply an update because we’re going to use it when the database is created or updated to recognize whether we’re using the latest version.

After you’ve modified your entities or the DataContext definition in your project, you can use the following methods:

  • AddTable<T>() if you’ve added a new table (of type T).
  • AddColumn<T>() if you’ve added a new column to a table (of type T).
  • AddAssociation<T>() if you’ve added a new relationship to a table (of type T).

The following sample code is executed when the application starts and needs to take care of the schema update process:

We’re assuming that the current database’s schema version is 2. In case the database doesn’t exist, we simply create it and, using the DatabaseSchemaUpdater class, we update the DatabaseSchemaVersion property. This way, the next time the data will be needed, the update operation won’t be executed since we’re already working with the latest version.

Instead, if the database already exists, we check the version number. If it’s an older version, we update the current schema. In the previous sample, we’ve added a new column to the Person table, called BirthDate (which is the parameter requested by the AddColumn<T>() method). Also in this case we need to remember to properly set the DatabaseSchemaVersion property to avoid further executions of the update operation.

In both cases, we need to apply the described changes by calling the Execute() method.

SQL Server Compact Toolbox: An Easier Way to Work With SQL CE

Erik Ej, a Microsoft MVP, has developed a powerful Visual Studio tool called SQL Server Compact Toolbox that can be very helpful for dealing with SQL CE and Windows Phone applications.

Two versions of the tool are available:

  • As an extension that’s integrated into commercial versions of Visual Studio.
  • As a stand-alone tool for Visual Studio Express since it does not support extensions.

The following are some of the features supported by the tool:

  • Automatically create entities and a DataContext class starting from an already existing SQL CE database.
  • The generated DataContext is able to copy a database from your Visual Studio project to your application’s local storage. This way, you can start with a prepopulated database and, at the same time, have write access.
  • The generated DataContext supports logging in the Visual Studio Output Window so you can see the SQL queries generated by LINQ to SQL.

Using Databases: SQLite

SQLite, from a conceptual point of view, is a similar solution to SQL CE: it’s a stand-alone database solution, where data is stored in a single file without a DBMS requirement.

The pros of using SQLite are: 

  • It offers better performance than SQL CE, especially with large amounts of data.
  • It is open source and cross-platform; you’ll find a SQLite implementation for Windows 8, Android, iOS, web apps, etc.

SQLite support has been introduced only in Windows Phone 8 due to the new native code support feature (since the SQLite engine is written in native code), and it’s available as a Visual Studio extension that you can download from the Visual Studio website.

After you’ve installed it, you’ll find the SQLite for Windows Phone runtime available in the Add reference window, in the Windows Phone Extension section. Be careful; this runtime is just the SQLite engine, which is written in native code. If you need to use a SQLite database in a C# application, you’ll need a third-party library that is able to execute the appropriate native calls for you.

In actuality, there are two available SQLite libraries: sqlite-net and SQLite Wrapper for Windows Phone. Unfortunately, neither of them is as powerful and flexible as the LINQ to SQL library that is available for SQL CE.

Let’s take a brief look at them. We won’t dig too deeply. Since they’re in constant development, things can change very quickly.

Sqlite-net

Sqlite-net is a third-party library. The original version for Windows Store apps is developed by Frank A. Krueger, while the Windows Phone 8 port is developed by Peter Huene.

The Windows Phone version is available on GitHub. Its configuration procedure is a bit tricky and changes from time to time, so be sure to follow the directions provided by the developer on the project’s home page.

Sqlite-net offers a LINQ approach to use the database that is similar to the code-first one offered by LINQ to SQL with SQL CE.

For example, in sqlite-net, tables are mapped with your project’s entities. The difference is that, this time, attributes are not required since every property will be automatically translated into a column. Attributes are needed only if you need to customize the conversion process, as in the following sample:

Surname doesn’t have any attribute, so it will be automatically converted into a varchar column. Instead, we set Id as a primary key with an auto increment value, while we specify that Name can have a maximum length of 50 characters.

All the basic operations with the database are accomplished using the SQLiteAsyncConnection class, which exposes asynchronous methods to create tables, query the data, delete items, etc. It requires as an input parameter the local storage path where the database will be saved.

As with SQL CE and LINQ to SQL, we need to create the database before using it. This is done by calling the CreateTableAsync<T>() method for every table we need to create, where T is the table’s type. In the following sample, we create a table to store the Person entity:

We don’t have a method to verify whether the table already exists since it’s not needed; if the table we’re creating already exists, the CreateTableAsync<T>() method simply won’t do anything.

In a similar way to LINQ to SQL, queries are performed using the Table<T> object. The only difference is that all the LINQ methods are asynchronous.

In the previous sample, we retrieve all the Person objects whose name is Matteo.

Insert, update, and delete operations are instead directly executed using the SQLiteAsyncConnection object, which offers the InsertAsync(), UpdateAsync(), and DeleteAsync() methods. It is not required to specify the object’s type; sqlite-net will automatically detect it and execute the operation on the proper table. In the following sample, you can see how a new record is added to a table:

Sqlite-net is the SQLite library that offers the easiest approach, but it has many limitations. For example, foreign keys are not supported, so it’s not possible to easily manage relationships.

SQLite Wrapper for Windows Phone

SQLite Wrapper for Windows Phone has been developed directly by Microsoft team members (notably Peter Torr and Andy Wigley) and offers a totally different approach than sqlite-net. It doesn’t support LINQ, just plain SQL query statements.

The advantage is that you have total control and freedom, since every SQL feature is supported: indexes, relationships, etc. The downside is that writing SQL queries for every operation takes more time, and it’s not as easy and intuitive as using LINQ.

To learn how to configure the wrapper in your project, follow the instructions posted on the CodePlex project page. You’ll have to download the project’s source code and add the correct wrapper version to your solution—there are two separate libraries, one for Windows Phone 8 and one for Windows Store apps.

The key class is called Database, which takes care of initializing the database and offers all the methods needed to perform the queries. As a parameter, you need to set the local storage path to save the database. If the path doesn’t exist, it will be automatically created. Then, you need to open the connection using the OpenAsync() method. Now you are ready to perform operations.

There are two ways to execute a query based on the value it returns.

If the query doesn’t return a value—for example, a table creation—you can use the ExecuteStatementAsync() method as shown in the following sample:

The previous method simply executes the query against the opened database. In the sample, we create a People table with two fields, Name and Surname.

The query, instead, can contain some dynamic parameters or return some values. In this case, we need to introduce a new class called Statement as demonstrated in the following sample:

The Statement class identifies a query, but it allows additional customization to be performed with it. In the sample, we use it to assign a dynamic value to the Name and Surname parameters. We set the placeholder using the @ prefix (@name and @surname), and then we assign them a value using the BindTextParameterWithName() method, passing the parameter’s name and the value.

BindTextParameterWithName() isn’t the only available method, but it’s specifically for string parameters. There are other methods based on the parameter’s type, such as BindIntParameterWithName() for numbers.

To execute the query, we use the StepAsync() method. Its purpose isn’t just to execute the query, but also to iterate the resulting rows.

In the following sample, we can see how this method can be used to manage the results of a SELECT query:

The StepAsync() method is included inside a while statement. At every loop iteration, we’ll get the reference to the next row returned by the query, starting from the first one. After we’ve iterated all the rows, the application will quit the while loop.

When we have a row’s reference, we can access its values by using the column index and the Get() method. We have a Get() variant for every data type, like GetText(), GetInt(), etc.

Another way is to access the columns using the Columns collection with the column name as the index. In this case, you first have to call the EnableColumnsProperty() method, as shown in the following sample:

Keep in mind that this approach is slower than using the column’s index.

Conclusion

This article delivered more key concepts that every Windows Phone developer should be familiar with. Managing local data is important, and in this article we’ve discussed the following approaches:

  • Correctly using files and folders in the isolated storage thanks to the Windows Runtime APIs.
  • Easily managing our application’s settings by using the IsolatedStorageSettings class.
  • Storing our application’s data using serialization and deserialization in simple app scenarios.
  • In case of more complex applications, we’ve seen how we can better organize our data using databases. We analyzed two available solutions: SQL CE and SQLite. They both offer a stand-alone database platform. SQL CE is exclusive to Windows Phone, but it is more powerful and easier to use; SQLite is open source and cross-platform, but you have to rely on third-party libraries which aren’t as powerful as LINQ to SQL for SQL CE.

This tutorial represents a chapter from Windows Phone 8 Succinctly, a free eBook from the team at Syncfusion.

2015-03-12T08:30:46.000Z2015-03-12T08:30:46.000ZMatteo Pagani

Swift from Scratch: Initialization and Initializer Delegation

$
0
0

In the previous installments of Swift from Scratch, we created a functional to-do application. The data model could use some love though. In this tutorial, we're going to refactor the data model by implementing a custom model class.

1. Data Model

The data model we're about to implement includes two classes, a Task class and a ToDo class that inherits from the Task class. While we create and implement these model classes, we continue our exploration of object-oriented programming in Swift. In this tutorial, we zoom in on the initialization of class instances and what role inheritance plays during initialization.

Task Class

Let's start with the implementation of the Task class. Create a new Swift file by selecting New > File... from Xcode's File menu. Choose Swift File from the iOS > Source section. Name the file Task.swift and hit Create.

The basic implementation is short and simple. The Task class inherits from NSObject, defined in the Foundation framework, and has a variable property name of type String. The class defines two initializers, init and init(name:). There are a few details that might trip you up so let me explain what's happening.

Because the init method is also defined in the NSObject class, we need to prefix the initializer with the override keyword. We covered overriding methods earlier in this series. In the init method, we invoke the init(name:) method, passing in "New Task" as the value for the name parameter.

The init(name:) method is another initializer, accepting a single parameter name of type String. In this initializer, the value of the name parameter is assigned to the name property. This is easy enough to understand. Right?

Designated and Convenience Initializers

What's with the convenience keyword prefixing the init method? Classes can have two types of initializers, designated initializers and convenience initializers. Convenience initializers are prefixed with the convenience keyword, which implies that init(name:) is a designated initializer. Why is that? What is the difference between designated and convenience initializers?

Designated initializers fully initialize an instance of a class, meaning that every property of the instance has an initial value after initialization. Looking at the Task class, for example, we see that the name property is set with the value of the name parameter of the init(name:) initializer. The result after initialization is a fully initialized Task instance.

Convenience initializers, however, rely on a designated initializer to create a fully initialized instance of the class. That's why the init initializer of the Task class invokes the init(name:) initializer in its implementation. This is referred to as initializer delegation. The init initializer delegates initialization to a designated initializer to create a fully initialized instance of the Task class.

Convenience initializers are optional. Not every class has a convenience initializer. Designated initializers are required and a class needs to have at least one designated initializer to create a fully initialized instance of itself.

NSCoding Protocol

The implementation of the Task class isn't complete though. Later in this article, we will write an array of ToDo instances to disk. This is only possible if instances of the ToDo class can be encoded and decoded.

Don't worry though, this isn't rocket science. We only need to make the Task and ToDo classes conform to the NSCoding protocol. That's why the Task class inherits form the NSObject class since the NSCoding protocol can only be implemented by classes inheriting—directly or indirectly—from NSObject. Like the NSObject class, the NSCoding protocol is defined in the Foundation framework.

Adopting a protocol is something we already covered in this series, but there are a few gotchas that I want to point out. Let's start by telling the compiler that the Task class conforms to the NSCoding protocol.

Next, we need to implement the two methods declared in the NSCoding protocol, init(coder:) and encodeWithCoder(_:). The implementation is straightforward if you're familiar with the NSCoding protocol.

The init(coder:) initializer is a designated initializer that initializes a Task instance. Even though we implement the init(coder:) method to conform to the NSCoding protocol, you won't ever need to invoke this method directly. The same is true for encodeWithCoder(_:), which encodes an instance of the Task class.

The required keyword prefixing the init(coder:) method indicates that every subclass of the Task class needs to implement this method. The required keyword only applies to initializers, which is why we don't need to add it to the encodeWithCoder(_:) method.

Before we move on, we need to talk about the @objc attribute. Because the NSCoding protocol is an Objective-C protocol, protocol conformance can only be checked by adding the @objc attribute. In Swift, there's no such thing as protocol conformance or optional protocol methods. In other words, if a class adheres to a particular protocol, the compiler verifies and expects that every method of the protocol is implemented.

ToDo Class

With the Task class implemented, it's time to implement the ToDo class. Create a new Swift file and name is ToDo.swift. Let's look at the implementation of the ToDo class.

The ToDo class inherits from the Task class and declares a variable property done of type Bool. In addition to the two required methods of the NSCoding protocol it inherits from the Task class, it also declares a designated initializer, init(name:done:).

As in Objective-C, the super keyword refers to the superclass, the Task class in this example. There is one important detail that deserves attention. Before you invoke the init(name:) method on the superclass, every property declared by the ToDo class needs to be initialized. In other words, before the ToDo class delegates initialization to its superclass, every property the ToDo class declares, needs to have a valid initial value. You can verify this by switching the order of the statements and inspect the error that pops up.

The same applies to the init(coder:) method. We first initialize the done property before invoking init(coder:) on the superclass. Also note that we downcast and force unwrap the result of decodeObjectForKey(_:) to a Bool using as!.

Initializers and Inheritance

When dealing with inheritance and initialization, there are a few rules to keep in mind. The rule for designated initializers are simple.

  • A designated initializer needs to invoke a designated initializer from its superclass. In the ToDo class, for example, the init(coder:) method invokes the init(coder:) method of its superclass. This is also referred to as delegating up.

The rules for convenience initializers are a bit more complex. There are two rules to keep in mind.

  • A convenience initializer always needs to invoke another initializer of the class it's defined in. In the Task class, for example, the init method is a convenience initializer and delegates initialization to another initializer, init(name:) in the example. This is known as delegating across.
  • Even though a convenience initializer doesn't have to delegate initialization to a designated initializer, a convenience initializer needs to call a designated initializer at some point. This is necessary to fully initialize the instance that's being initialized.

With both model classes implemented, it is time to refactor the ViewController and AddItemViewController classes. Let's start with the latter.

2. Refactoring AddItemViewController

Step 1: Updating AddItemViewControllerDelegate Protocol

The only changes we need to make in the AddItemViewController class are related to the AddItemViewControllerDelegate protocol. In the protocol declaration, change the type of didAddItem from String to ToDo, the model class we implemented earlier.

Step 2: Update create Action

This means that we also need to update the create action in which we invoke the delegate method. In the updated implementation, we create a ToDo instance, passing it to the delegate method.

3. Refactoring ViewController

Step 1: Updating items Property

The ViewController class requires a bit more work. We first need to change the type of the items property to [ToDo], an array of ToDo instances.

Step 2: Table View Data Source Methods

This also means that we need to refactor a few other methods, such as the cellForRowAtIndexPath(_:) method shown below. Because the items array now contains ToDo instances, checking if an item is marked as done is much simpler. We use Swift's ternary conditional operator to update the table view cell's accessory type.

When the user deletes an item, we only need to update the items property by removing the corresponding ToDo instance. This is reflected in the implementation of the tableView(_:commitEditingStyle:forRowAtIndexPath:) method shown below.

Step 3: Table View Delegate Methods

Updating the state of an item when the user taps a row is handled in the tableView(_:didSelectRowAtIndexPath:) method. The implementation of this UITableViewDelegate method is much simpler thanks to the ToDo class.

The corresponding ToDo instance is updated and this change is reflected by the table view. To save the state, we invoke saveItems instead of saveCheckedItems.

Step 4: Add Item View Controller Delegate Methods

Because we updated the AddItemViewControllerDelegate protocol, we also need to update the ViewController's implementation of this protocol. The change, however, is simple. We only need to update the method signature.

Step 5: Saving Items

pathForItems

Instead of storing the items in the user defaults database, we're going to store them in the application's documents directory. Before we update the loadItems and saveItems methods, we're going to implement a helper method named pathForItems. The method is private and returns a path, the location of the items in the documents directory.

We first fetch the path to the documents directory in the application's sandbox by invoking NSSearchPathForDirectoriesInDomains(_:_:_:). Because this method returns an array of strings, we grab the first item, force unwrap it, and downcast it to a String. The value we return from pathForItems is composed of the path to the documents directory with the string "items" appended to it.

loadItems

The loadItems method changes quite a bit. We first store the result of pathForItems in a constant named path. We then unarchive the object archived at that path and downcast it to an optional array of ToDo instances. We use optional binding to unwrap the optional and assign it to a constant named items. In the if clause, we assign the value stored in items to the items property.

saveItems

The saveItems method is short and simple. We store the result of pathForItems in a constant named path and invoke archiveRootObject(_:toFile:) on NSKeyedArchiver, passing in the items property and path. We print the result of the operation to the console.

Step 6: Cleaning Up

Let's end with the fun part, deleting code. Start by removing the checkedItems property at the top since we no longer need it. As a result, we can also remove the loadCheckedItems and saveCheckedItems methods, and every reference to these methods in the ViewController class.

Build and run the application to see if everything is still working. The data model makes the application's code much simpler and reliable. Thanks to the ToDo class, managing the items in our list much is now easier and less error-prone.

Conclusion

In this tutorial, we refactored the data model of our application. You learned more about object-oriented programming and inheritance. Instance initialization is an important concept in Swift so make sure you understand what we've covered in this tutorial. You can read more about initialization and initializer delegation in The Swift Programming Language.

2015-03-13T17:50:16.000Z2015-03-13T17:50:16.000ZBart Jacobs

Swift from Scratch: Initialization and Initializer Delegation

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

In the previous installments of Swift from Scratch, we created a functional to-do application. The data model could use some love though. In this tutorial, we're going to refactor the data model by implementing a custom model class.

1. Data Model

The data model we're about to implement includes two classes, a Task class and a ToDo class that inherits from the Task class. While we create and implement these model classes, we continue our exploration of object-oriented programming in Swift. In this tutorial, we zoom in on the initialization of class instances and what role inheritance plays during initialization.

Task Class

Let's start with the implementation of the Task class. Create a new Swift file by selecting New > File... from Xcode's File menu. Choose Swift File from the iOS > Source section. Name the file Task.swift and hit Create.

The basic implementation is short and simple. The Task class inherits from NSObject, defined in the Foundation framework, and has a variable property name of type String. The class defines two initializers, init and init(name:). There are a few details that might trip you up so let me explain what's happening.

Because the init method is also defined in the NSObject class, we need to prefix the initializer with the override keyword. We covered overriding methods earlier in this series. In the init method, we invoke the init(name:) method, passing in "New Task" as the value for the name parameter.

The init(name:) method is another initializer, accepting a single parameter name of type String. In this initializer, the value of the name parameter is assigned to the name property. This is easy enough to understand. Right?

Designated and Convenience Initializers

What's with the convenience keyword prefixing the init method? Classes can have two types of initializers, designated initializers and convenience initializers. Convenience initializers are prefixed with the convenience keyword, which implies that init(name:) is a designated initializer. Why is that? What is the difference between designated and convenience initializers?

Designated initializers fully initialize an instance of a class, meaning that every property of the instance has an initial value after initialization. Looking at the Task class, for example, we see that the name property is set with the value of the name parameter of the init(name:) initializer. The result after initialization is a fully initialized Task instance.

Convenience initializers, however, rely on a designated initializer to create a fully initialized instance of the class. That's why the init initializer of the Task class invokes the init(name:) initializer in its implementation. This is referred to as initializer delegation. The init initializer delegates initialization to a designated initializer to create a fully initialized instance of the Task class.

Convenience initializers are optional. Not every class has a convenience initializer. Designated initializers are required and a class needs to have at least one designated initializer to create a fully initialized instance of itself.

NSCoding Protocol

The implementation of the Task class isn't complete though. Later in this article, we will write an array of ToDo instances to disk. This is only possible if instances of the ToDo class can be encoded and decoded.

Don't worry though, this isn't rocket science. We only need to make the Task and ToDo classes conform to the NSCoding protocol. That's why the Task class inherits form the NSObject class since the NSCoding protocol can only be implemented by classes inheriting—directly or indirectly—from NSObject. Like the NSObject class, the NSCoding protocol is defined in the Foundation framework.

Adopting a protocol is something we already covered in this series, but there are a few gotchas that I want to point out. Let's start by telling the compiler that the Task class conforms to the NSCoding protocol.

Next, we need to implement the two methods declared in the NSCoding protocol, init(coder:) and encodeWithCoder(_:). The implementation is straightforward if you're familiar with the NSCoding protocol.

The init(coder:) initializer is a designated initializer that initializes a Task instance. Even though we implement the init(coder:) method to conform to the NSCoding protocol, you won't ever need to invoke this method directly. The same is true for encodeWithCoder(_:), which encodes an instance of the Task class.

The required keyword prefixing the init(coder:) method indicates that every subclass of the Task class needs to implement this method. The required keyword only applies to initializers, which is why we don't need to add it to the encodeWithCoder(_:) method.

Before we move on, we need to talk about the @objc attribute. Because the NSCoding protocol is an Objective-C protocol, protocol conformance can only be checked by adding the @objc attribute. In Swift, there's no such thing as protocol conformance or optional protocol methods. In other words, if a class adheres to a particular protocol, the compiler verifies and expects that every method of the protocol is implemented.

ToDo Class

With the Task class implemented, it's time to implement the ToDo class. Create a new Swift file and name is ToDo.swift. Let's look at the implementation of the ToDo class.

The ToDo class inherits from the Task class and declares a variable property done of type Bool. In addition to the two required methods of the NSCoding protocol it inherits from the Task class, it also declares a designated initializer, init(name:done:).

As in Objective-C, the super keyword refers to the superclass, the Task class in this example. There is one important detail that deserves attention. Before you invoke the init(name:) method on the superclass, every property declared by the ToDo class needs to be initialized. In other words, before the ToDo class delegates initialization to its superclass, every property the ToDo class declares, needs to have a valid initial value. You can verify this by switching the order of the statements and inspect the error that pops up.

The same applies to the init(coder:) method. We first initialize the done property before invoking init(coder:) on the superclass. Also note that we downcast and force unwrap the result of decodeObjectForKey(_:) to a Bool using as!.

Initializers and Inheritance

When dealing with inheritance and initialization, there are a few rules to keep in mind. The rule for designated initializers are simple.

  • A designated initializer needs to invoke a designated initializer from its superclass. In the ToDo class, for example, the init(coder:) method invokes the init(coder:) method of its superclass. This is also referred to as delegating up.

The rules for convenience initializers are a bit more complex. There are two rules to keep in mind.

  • A convenience initializer always needs to invoke another initializer of the class it's defined in. In the Task class, for example, the init method is a convenience initializer and delegates initialization to another initializer, init(name:) in the example. This is known as delegating across.
  • Even though a convenience initializer doesn't have to delegate initialization to a designated initializer, a convenience initializer needs to call a designated initializer at some point. This is necessary to fully initialize the instance that's being initialized.

With both model classes implemented, it is time to refactor the ViewController and AddItemViewController classes. Let's start with the latter.

2. Refactoring AddItemViewController

Step 1: Updating AddItemViewControllerDelegate Protocol

The only changes we need to make in the AddItemViewController class are related to the AddItemViewControllerDelegate protocol. In the protocol declaration, change the type of didAddItem from String to ToDo, the model class we implemented earlier.

Step 2: Update create Action

This means that we also need to update the create action in which we invoke the delegate method. In the updated implementation, we create a ToDo instance, passing it to the delegate method.

3. Refactoring ViewController

Step 1: Updating items Property

The ViewController class requires a bit more work. We first need to change the type of the items property to [ToDo], an array of ToDo instances.

Step 2: Table View Data Source Methods

This also means that we need to refactor a few other methods, such as the cellForRowAtIndexPath(_:) method shown below. Because the items array now contains ToDo instances, checking if an item is marked as done is much simpler. We use Swift's ternary conditional operator to update the table view cell's accessory type.

When the user deletes an item, we only need to update the items property by removing the corresponding ToDo instance. This is reflected in the implementation of the tableView(_:commitEditingStyle:forRowAtIndexPath:) method shown below.

Step 3: Table View Delegate Methods

Updating the state of an item when the user taps a row is handled in the tableView(_:didSelectRowAtIndexPath:) method. The implementation of this UITableViewDelegate method is much simpler thanks to the ToDo class.

The corresponding ToDo instance is updated and this change is reflected by the table view. To save the state, we invoke saveItems instead of saveCheckedItems.

Step 4: Add Item View Controller Delegate Methods

Because we updated the AddItemViewControllerDelegate protocol, we also need to update the ViewController's implementation of this protocol. The change, however, is simple. We only need to update the method signature.

Step 5: Saving Items

pathForItems

Instead of storing the items in the user defaults database, we're going to store them in the application's documents directory. Before we update the loadItems and saveItems methods, we're going to implement a helper method named pathForItems. The method is private and returns a path, the location of the items in the documents directory.

We first fetch the path to the documents directory in the application's sandbox by invoking NSSearchPathForDirectoriesInDomains(_:_:_:). Because this method returns an array of strings, we grab the first item, force unwrap it, and downcast it to a String. The value we return from pathForItems is composed of the path to the documents directory with the string "items" appended to it.

loadItems

The loadItems method changes quite a bit. We first store the result of pathForItems in a constant named path. We then unarchive the object archived at that path and downcast it to an optional array of ToDo instances. We use optional binding to unwrap the optional and assign it to a constant named items. In the if clause, we assign the value stored in items to the items property.

saveItems

The saveItems method is short and simple. We store the result of pathForItems in a constant named path and invoke archiveRootObject(_:toFile:) on NSKeyedArchiver, passing in the items property and path. We print the result of the operation to the console.

Step 6: Cleaning Up

Let's end with the fun part, deleting code. Start by removing the checkedItems property at the top since we no longer need it. As a result, we can also remove the loadCheckedItems and saveCheckedItems methods, and every reference to these methods in the ViewController class.

Build and run the application to see if everything is still working. The data model makes the application's code much simpler and reliable. Thanks to the ToDo class, managing the items in our list much is now easier and less error-prone.

Conclusion

In this tutorial, we refactored the data model of our application. You learned more about object-oriented programming and inheritance. Instance initialization is an important concept in Swift so make sure you understand what we've covered in this tutorial. You can read more about initialization and initializer delegation in The Swift Programming Language.

2015-03-13T17:50:16.000Z2015-03-13T17:50:16.000ZBart Jacobs

Add Charts to Your Android App Using MPAndroidChart

$
0
0

If your app deals with a lot of data, using charts instead of tables to display that data could lead to a vastly better user experience. In this tutorial, you are going to learn about a popular open source charting library MPAndroidChart. The charts of this library are highly customizable, interactive, and easy to create.

Prerequisites

Make sure that you have the latest version of Android Studio installed. You can get it from the Android Developer website.

1. Adding MPAndroidChart to a Project

To use this library in your Android project, all you have to do is:

  1. Download the latest version of the library from Github. At the time of writing, the latest version is 1.7.4.
  2. Copy mpandroidchartlibrary-1-7-4.jar to your project's libs directory.
  3. In Android Studio, right click the JAR file and select Add as Library.

2. Creating a DataSet

All data should be converted into a DataSet object before it can be used by a chart. Different types of charts use different subclasses of the DataSet class. For example, a BarChart uses a BarDataSet instance. Similarly, a PieChart uses a PieDataSet instance.

Instead of simply dealing with random numbers to generate a sample chart, let's consider a hypothetical scenario. Alice and Bob are friends. Alice calls Bob several times a month to know what he's up to. Bob makes a note whenever she calls him.

In this tutorial, we use Bob's notes to create a chart to show the number of times Alice called Bob. Here's what Bob has noted down:

Month
Number of Calls
January4
February8
March6
April12
May18
June9

A bar chart seems perfect for this type of data. To display the data in a chart, we need to create a BarDataSet instance. You can follow the same steps to create instances of other subclasses of DataSet.

Every individual value of the raw data should be represented as an Entry. An ArrayList of such Entry objects is used to create a DataSet. Let's create a few BarEntry objects and add them to an ArrayList:

Now that the ArrayList of Entry objects is ready, we can create a DataSet out of it:

3. Defining the X-Axis Labels

We've already added several values to our chart, but they won't make much sense to the user unless we give them meaningful labels. Each x-axis label is represented using a String and an ArrayList is used to store all the labels.

4. Creating a Chart

All charts of this library are subclasses of ViewGroup, which means that you can easily add them to any layout. You can define your chart using an XML file or Java code. If the chart is going to take up the entire screen of an Activity or Fragment, then using Java code is easier:

This creates a blank chart without any data. Let's use the data set and list of labels we created in the previous steps to define this chart's data.

Let's also add a description to the chart.

If you now run your app on an Android device, you should be able to see a bar chart that looks similar to the one shown below. The chart is interactive and responds to pinch-to-zoom and dragging gestures.

5. Using Color Templates

If you do not like the default colors, you can use the DataSet class's setColors method to change the color scheme. However, MPAndroidChart also comes with a number of predefined color templates that let you change the look and feel of your data set without having to deal with the individual color values.

In the current version of this library, the following templates are available:

  • ColorTemplate.LIBERTY_COLORS
  • ColorTemplate.COLORFUL_COLORS
  • ColorTemplate.JOYFUL_COLORS
  • ColorTemplate.PASTEL_COLORS
  • ColorTemplate.VORDIPLOM_COLORS

To associate a color template with a data set, you have to use the setColors method. Here's an example:

Run your app one more time to see a chart with more vibrant colors.

6. Adding Animations

All charts of this library support animations, which you can use to make your charts appear more lively. The animateXY method is used to animate both axes of the chart. If you want to animate only one of the axes, you can use animateX or animateY to animate the x-axis or y-axis respectively. You have to specify the duration (in milliseconds) of the animation when you call these methods. For example, to only animate the y-Axis, add the following code snippet:

7. Using Limit Lines

You can add limit lines to a chart to add more meaning to your charts. Limit lines only make sense for certain types of charts, such as bar charts, line charts, and scatter charts.

In our example, where Alice calls Bob several times a month, let's say that Bob gets annoyed if Alice calls him more than ten times per month. To show this information, we could add a limit line for that value. Here's how you do this:

8. Saving the Chart as an Image

MPAndroidChart also enables you to save the current state of a chart as an image. To use this feature, you first need to give your app the permission to write to the device's SD Card. You can do this by adding the following code to your AndroidManifest.xml:

You have two methods to choose from:

  • saveToGallery This method saves your chart as a JPEG file. It also lets you specify the quality or the compression ratio of the image.
  • saveToPath This method saves your chart as a PNG file to the path you specify.

For example, to save your chart as a JPEG file, you could use the following code snippet:

Conclusion

In this tutorial, you learned how to use the MPAndroidChart library to create charts that are both pleasing and interactive. For the sake of consistency, I have used bar charts throughout this tutorial. However, you can follow the same steps to create other types of charts. To learn more about this library, I encourage you to read the documentation and examples on Github.

2015-03-16T16:15:57.000Z2015-03-16T16:15:57.000ZAshraff Hathibelagal

Add Charts to Your Android App Using MPAndroidChart

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

If your app deals with a lot of data, using charts instead of tables to display that data could lead to a vastly better user experience. In this tutorial, you are going to learn about a popular open source charting library MPAndroidChart. The charts of this library are highly customizable, interactive, and easy to create.

Prerequisites

Make sure that you have the latest version of Android Studio installed. You can get it from the Android Developer website.

1. Adding MPAndroidChart to a Project

To use this library in your Android project, all you have to do is:

  1. Download the latest version of the library from Github. At the time of writing, the latest version is 1.7.4.
  2. Copy mpandroidchartlibrary-1-7-4.jar to your project's libs directory.
  3. In Android Studio, right click the JAR file and select Add as Library.

2. Creating a DataSet

All data should be converted into a DataSet object before it can be used by a chart. Different types of charts use different subclasses of the DataSet class. For example, a BarChart uses a BarDataSet instance. Similarly, a PieChart uses a PieDataSet instance.

Instead of simply dealing with random numbers to generate a sample chart, let's consider a hypothetical scenario. Alice and Bob are friends. Alice calls Bob several times a month to know what he's up to. Bob makes a note whenever she calls him.

In this tutorial, we use Bob's notes to create a chart to show the number of times Alice called Bob. Here's what Bob has noted down:

Month
Number of Calls
January4
February8
March6
April12
May18
June9

A bar chart seems perfect for this type of data. To display the data in a chart, we need to create a BarDataSet instance. You can follow the same steps to create instances of other subclasses of DataSet.

Every individual value of the raw data should be represented as an Entry. An ArrayList of such Entry objects is used to create a DataSet. Let's create a few BarEntry objects and add them to an ArrayList:

Now that the ArrayList of Entry objects is ready, we can create a DataSet out of it:

3. Defining the X-Axis Labels

We've already added several values to our chart, but they won't make much sense to the user unless we give them meaningful labels. Each x-axis label is represented using a String and an ArrayList is used to store all the labels.

4. Creating a Chart

All charts of this library are subclasses of ViewGroup, which means that you can easily add them to any layout. You can define your chart using an XML file or Java code. If the chart is going to take up the entire screen of an Activity or Fragment, then using Java code is easier:

This creates a blank chart without any data. Let's use the data set and list of labels we created in the previous steps to define this chart's data.

Let's also add a description to the chart.

If you now run your app on an Android device, you should be able to see a bar chart that looks similar to the one shown below. The chart is interactive and responds to pinch-to-zoom and dragging gestures.

5. Using Color Templates

If you do not like the default colors, you can use the DataSet class's setColors method to change the color scheme. However, MPAndroidChart also comes with a number of predefined color templates that let you change the look and feel of your data set without having to deal with the individual color values.

In the current version of this library, the following templates are available:

  • ColorTemplate.LIBERTY_COLORS
  • ColorTemplate.COLORFUL_COLORS
  • ColorTemplate.JOYFUL_COLORS
  • ColorTemplate.PASTEL_COLORS
  • ColorTemplate.VORDIPLOM_COLORS

To associate a color template with a data set, you have to use the setColors method. Here's an example:

Run your app one more time to see a chart with more vibrant colors.

6. Adding Animations

All charts of this library support animations, which you can use to make your charts appear more lively. The animateXY method is used to animate both axes of the chart. If you want to animate only one of the axes, you can use animateX or animateY to animate the x-axis or y-axis respectively. You have to specify the duration (in milliseconds) of the animation when you call these methods. For example, to only animate the y-Axis, add the following code snippet:

7. Using Limit Lines

You can add limit lines to a chart to add more meaning to your charts. Limit lines only make sense for certain types of charts, such as bar charts, line charts, and scatter charts.

In our example, where Alice calls Bob several times a month, let's say that Bob gets annoyed if Alice calls him more than ten times per month. To show this information, we could add a limit line for that value. Here's how you do this:

8. Saving the Chart as an Image

MPAndroidChart also enables you to save the current state of a chart as an image. To use this feature, you first need to give your app the permission to write to the device's SD Card. You can do this by adding the following code to your AndroidManifest.xml:

You have two methods to choose from:

  • saveToGallery This method saves your chart as a JPEG file. It also lets you specify the quality or the compression ratio of the image.
  • saveToPath This method saves your chart as a PNG file to the path you specify.

For example, to save your chart as a JPEG file, you could use the following code snippet:

Conclusion

In this tutorial, you learned how to use the MPAndroidChart library to create charts that are both pleasing and interactive. For the sake of consistency, I have used bar charts throughout this tutorial. However, you can follow the same steps to create other types of charts. To learn more about this library, I encourage you to read the documentation and examples on Github.

2015-03-16T16:15:57.000Z2015-03-16T16:15:57.000ZAshraff Hathibelagal

Localizing an iOS Application in Xcode 6

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

Translating an iOS application into different languages is a two-step processes. First, you need to prepare your app by separating all user-facing text, images, and other resources that need to be translated from the rest of your code and storyboards. This process is called internationalization (I18N).

After you’ve finished internationalizing your app, you’re ready to localize it. This is where you export your resources and send them off to your translator. When you get the translated resources back, you simply import them back into Xcode, and your app is ready to support another language.

1. Setup

We’ll be using a simple example app to experiment with localizations. Create a new Xcode project, use Single View Application for the template, and call the project LocalizationExample.

Next, we need to create a simple user interface so we can see our localizations in action. In Main.storyboard, add a label and an image view. Change the label's text to "Hello, World!". Download these image resources, add en/logo.png to your Xcode project (make sure Copy items if needed is checked), and display it in the image view by changing its Image field to logo.png. Also be sure to add a Center Horizontally in Container layout constraint to both user interface elements.

You also need to know how to localize hard-coded strings so go ahead and add a console message to AppDelegate.m. Add the following log statement to applicationDidFinishLaunching:.

This gives us three resources to localize, an image, a label, and a hard-coded string. Note that developing a localized app is largely the same as creating a non-localized app. You can configure views and define custom behavior without really worrying about localization. Most of it happens after you've got your basic functionality working.

2. Internationalization

Now that we have a basic application to work with, we're ready to internationalize our app. This is where we prepare for localizing resources by isolating them from the rest of our code. Xcode provides extensive I18N capabilities, which makes it much easier to localize an app.

Step 1: Preparing Storyboards

First, let's take a look at internationalizing our app's user interface. The first step is to tell Xcode which regions, or locales, you want to support. Click the LocalizationsExample project in the Project Navigator and select the blue project icon in the pop-up list to the top-left.

The Localizations section is where you can add locales to your app. We'll be translating our example project into Spanish, so click the plus sign and select Spanish (es). This will open a dialog window asking you what you want to do with your existing resources. Make sure Localizable Strings is selected for both Main.storyboard and LaunchScreen.xib as shown in the following screenshot. Click Finish to continue.

You’ll now find two items under Main.storyboard, a base storyboard and a Main.strings file. The former is your actual storyboard file and the latter is a strings file that contains all the user-facing text in the storyboard. This strings file is what will eventually be translated.

The Main.storyboard file is now internationalized and ready to be localized.

Step 2: Preparing Hard-Coded Strings

User-facing strings that are hard-coded into your Objective-C/Swift classes need some special processing. This is a necessary step, for example, if you're programmatically setting the text for user interface elements in your storyboards.

Fortunately, internationalizing hard-coded strings is a straightforward process. All you have to do is wrap them in an NSLocalizedString macro, like so:

The first argument is a key pointing to the string you're looking for and the second (optional) argument is a comment that will be included in the exported strings file. You can use abstract, dictionary-style keys (e.g., @"greeting"), but I find that code is more readable if you use the actual string to be translated as the key.

In the next section, any NSLocalizedString calls will automatically be pulled out of our code and added to the list of strings that need to be translated.

3. Localization

Once your app is internationalized, you're ready to start localizing your resources. Localization is a fairly simple process where you export all of the strings that need to be translated, pass them off to your translator, and import them back into your project. This export/translate/import cycle can continue as you're developing your app, but it's usually a good idea to finalize the majority of your user interface before starting the localization process.

Step 1: Exporting Strings

Xcode makes it easy to export all of your internationalized strings to a single XML Localization Interchange File Format (.xliff) document, which is the standard format for the localization industry.

To generate this file, selecting LocalizationExample in the Project Navigator, choose Editor > Export For Localization... from Xcode's menu, and select a file path outside of your Xcode project to prevent any potential confusion.

Clicking Save will create a new folder containing an es.xliff file. If you open it, you'll find a whole lot of XML containing information about every string in your app that needs to be localized.

This is the file that you need to send off to your translator. They’ll have special tools for editing the XML, but for our example, let’s go in and edit it directly. Open es.xliff and search for the text "Hello, World!". You should find two separate <trans-unit> elements as shown below.

As you can see from the <note> element, the first one is the text from our label element and the second one is the hard-coded string that we wrapped in NSLocalizedString.

Change the <target> element to "Hola, Mundo!" for both of these. You may need to add a <target> element to the second one. Our translated strings are now ready to be loaded back into Xcode.

Step 2: Importing Strings

Once your translator finishes work on a .xliff file, you need to load it back into your Xcode project. With LocalizationExample selected in the Project Navigator, choose Editor > Import Localizations... from Xcode's menu. Navigate to the es.xliff file that we updated in the previous section and hit the Import button.

We've successfully added a Spanish translation to our app. If you open up Main.strings, you'll see the translated label text. You'll also find a new Localizable.strings file in the Supporting Files group that contains contains the translation of our NSLocalizedString message.

We'll test these translations in a moment, but first we need to take a look at localizing resources that aren't strings.

Step 3: Localizing Images

Localizing image resources is a little bit different than localizing strings. Select logo.png and hit the Localize... button in the File Inspector.

This will bring up a dialog asking which locale this image represents. Select English and hit the Localize button. The Localization section will turn into a list of checkboxes. Select both the English and Spanish checkboxes.

The image is now localized, but we still need to go into our Xcode project and manually replace the Spanish version of the image. Using Finder, navigate to the folder containing your Xcode project and open the LocalizationExample folder. You'll find an en.lproj and an es.lproj folder.

This is how an iOS app internally represents its localized resources. English resources are in the en.lproj folder, Spanish ones in the es.lproj folder, and shared resources in Base.lproj folder. Replace es.lproj/logo.png with the es/logo.png image that you downloaded at the beginning of this tutorial. Other resources, such as data, sound, and video files can be localized in the same manner.

4. Testing Localizations

You should always test your localizations on an actual device, but it's also possible to test them in the iOS simulator using schemes. Navigate to the Product > Scheme > Edit Scheme... menu item in Xcode to bring up the scheme editor. With Run selected in the list to the left, open the Options tab and change the Application Language to Spanish.

That's all there is to it. The next time you run the app in the iOS simulator, you'll see the Spanish version of the label, image view, and console message.

Conclusion

Localizing an iOS application requires additional work, but Xcode makes the process easy and straightforward. In this tutorial, you have learned the difference between internationalization and localization, and you've also learned about the steps involved to localize strings and resources in an iOS application using Xcode's built-in tools.

2015-03-18T16:45:47.000Z2015-03-18T16:45:47.000ZRyan Hodson

Windows Phone 8 Succinctly: Data Access—Network

$
0
0

Checking the Internet Connection

All Windows Phone devices have a built-in network connection but, for the same reason we learned how to locally store data, we need to be ready to manage how users are using our application while a connection is missing.

For this purpose, the Windows Phone framework includes a class that can be used to discover information about the Internet connection called DeviceNetworkInformation, which is part of the Microsoft.Phone.Net.NetworkInformation namespace.

The most important one is IsNetworkAvailable, which tells us whether an Internet connection is available. We should always use this API before performing an operation that requires a connection, like the following sample:

The class also offers an event called NetworkAvailabilityChanged which is triggered every time the connection status changes. It’s useful if you want to quickly react to network changes, such as enabling or disabling certain application features.

The return parameters contain a property called NotificationType, of the type NetworkNotificationType, which tells us the current network status.

However, with the DeviceNetworkInformation you’ll be able to also get other information about the current network status, like whether the user has enabled the cellular data connection (IsCellularDataEnabled), the Wi-Fi connection (IsWiFiEnabled), or roaming options (IsCellularDataRoamingOptions).

The framework offers another useful class to deal with network connections called NetworkInterface. By using the NetworkInterfaceType property, you’ll be able to identify which connection type is currently in use. For example, we can use this property to avoid downloading big files while using a cellular connection.

NetworkInterfaceType is an enumerator that can assume many values. The most important ones are:

  • MobileBroadbandGsm and MobileBroadbandCdma when the phone is connected to a cellular network (GSM or CDMA, according to the country)
  • Wireless80211, when the phone is connected to a Wi-Fi network

In the following sample, we display a message on the screen with the current connection type:

Performing Network Operations: HttpClient

The Windows Phone framework has two built-in classes for performing network operations: WebClient and HttpWebRequest. Unfortunately, neither of them is perfect. WebClient is very easy to use, but it’s based on the old callback approach (unless you install the Async for .NET package we discussed earlier in this series). HttpWebRequest is very powerful, but it is complex to use and based on an old asynchronous pattern that is hard to understand.

The Windows Runtime has introduced a new class called HttpClient, which takes the best of both worlds. It’s powerful and offers great performance, but it’s easy to use and offers methods that are based on the new async and await pattern. This class is available in the full Windows Runtime for Windows Store apps, but it’s not included in the Windows Phone Runtime subset—you’ll have to install it from NuGet.

The HttpClient class, as we’ll see later, is great not just for performing generic network operations like downloading and uploading file, but also for interacting with web services. In fact, it exposes asynchronous methods for every HTTP command, like GET, POST, PUT, etc.

Note: To be able to interact with the network you’ll have to enable the ID_CAP_NETWORKING option in the manifest file. It is enabled in every new Windows Phone project by default.

Downloading Data

Files are usually downloaded using the GET HTTP command, so HttpClient offers the GetAsync() method. To make developers’ lives simpler, HttpClient has some built-in methods to download the most common file types, such as GetStringAsync() for downloading text files like XML, RSS, or REST responses; or GetByteArrayAsync() and GetStreamAsync() to get binary file content.

Downloading strings is really easy. The method GetStringAsync() requires as a parameter the file’s URL and returns the file’s content as a string. In the following sample, you can see how to download my blog’s RSS feed:

Once you have the string, you can perform the required operations according to your scenario. For example, in the previous sample I could have parsed the returned XML with LINQ to XML to display the news list on the screen.

Downloading binary files can be accomplished in many ways. You can use GetByteArrayAsync() if you prefer to work with bytes, or GetStreamAsync() if you prefer to manipulate the file’s content as a stream.

In the following sample, you’ll see how to download a picture using the GetByteArrayAsync() method. It returns a byte’s array, which can be easily saved in the local storage using the APIs we learned about earlier in this series.

By using the DataWriter class, we’re able to save the byte array returned by the HttpClient class into a file in the local storage called picture.png.

If you need full control over the download operation, you can use the generic GetAsync() method, which returns a HttpResponseMessage object with the entire response’s content, like headers, status code, etc.

In the following sample you can see how, by using the GetAsync() method, we’re able to download a picture as a Stream and display it in an Image control placed on the page. To the method we pass a second parameter of type HttpCompletionOption, which tells the class when to mark the operation as completed. Since we want the full content of the response (which is the downloaded image), we use the ResponseContentRead option.

Notice that the specific methods we’ve seen offered by the HttpClient class are simply a shortcut to the methods offered by the Content property of the HttpResponseMessage class (in the previous sample, we use the ReadAsStreamAsync() method to return the response’s content as a Stream).

Uploading Data

Uploading data is accomplished in a similar way: the operation is usually performed using the POST command, so the HttpClient class exposes the PostAsync() method for this purpose.

The content to send is prepared using the HttpContent class, which offers many implementations: StreamContent to send a file’s stream, ByteArrayContent to send a binary file, StringContent to send a string, or MultipartFormDataContent to send content encoded using multipart/form-data MIME type.

In the following sample, you can see how to upload a file’s stream to a service:

After we have retrieved the stream of a file stored in the local storage, we pass it to a new instance of the StreamContent class. Then, we call the PostAsync() method, passing the service’s URL and the HttpContent object as parameters.

Using REST Services

REST (Representational State Transfer) is, without a doubt, the most used approach nowadays in web service development, especially in the mobile world.

REST services have become very popular for two reasons:

  • They are based on the HTTP protocol and they expose operations using the standard HTTP commands (like GET, POST, PUT, etc.).
  • They return data using standard languages like XML and JSON.

Almost every platform natively supports these technologies, so you don’t have to look for special libraries to interact with them as is needed for WSDL-based web services.

We’ve already seen how, with the HttpClient class, it’s simple to interact with the web by using the standard HTTP commands. Most of the time, to interact with a REST service, you’ll simply have to execute the GetStringAsync() method to get the XML or JSON response.

Once you have the result, most of the time you’ll have to convert it into objects to be used inside the application. Earlier in this series, we discussed the easiest way to accomplish this task: deserialization, which means translating plain text into complex objects. We can use the DataContractSerializer or DataContractJsonSerializer classes to do this. In this case, you just have to refer to the deserialization process since the procedure is the same.

We assume that the service returns, in JSON format, a list of persons:

With the help of the DataContractJsonSerializer class, we are able to convert the previous JSON into a list of Person objects, which is the same class we have used in many other samples in this series. The difference in this sample is that we are able to control the serialization process, in case, for example, the property names returned from the JSON are different than the ones we use in our classes. This is a very common scenario when dealing with JSON since property names are typically lowercase, while in C# objects they are CamelCase. This result is achieved by using the [DataMember] attribute, which can be applied to the properties we want to serialize. In the following sample, you can see that the attribute offers a property called Name, which can be used to specify which property name we expect to find in the JSON file.

This approach has a downside: REST services always return a plain string, while the DataContractJsonSerializer class requires a Stream as an input parameter of the ReadObject() method, so we’re always forced to convert it using a MemoryStream object.

There is another way to accomplish the same result. Let me introduce JSON.NET, a third-party library that offers some additional useful features for handling JSON data. In addition, it offers better performance and is able to deserialize complex JSON files quicker.

It can be easily installed using NuGet, and its official website offers comparisons with other JSON libraries and detailed documentation.

In the following sample, we use JSON.NET to achieve the same result as the code that we’ve previously used:

The JsonConvert class (which is part of the Newtonsoft.Json namespace) exposes the DeserializeObject<T>() method, where T is the object’s type we expect in return. As an input parameter, it requires only the JSON string that we’ve downloaded from the service.

It’s also possible to control the deserialization process using attributes, like we previously did with the DataMember attribute. In the following sample, you can see how we can manually define how JSON properties should be translated:

Tip: You will often have to use third-party services, so you won’t know the exact mapping between entities and JSON data. There is a website that will help you in this scenario: http://json2csharp.com/. Simply paste the JSON returned by your service, and it will generate for you the needed C# classes to map the JSON data. 

LINQ to JSON

Another interesting feature introduced by JSON.NET is LINQ to JSON, which is a LINQ-based language that, similar to LINQ to XML, can be used to manipulate a JSON string to extract just the information you need. This approach is useful when you do not really need to use deserialization, but just need to extract some data from the JSON response you received from the service.

The starting point to use LINQ to JSON is the JObject class, which identifies a JSON file. To start working with it, you simply have to call the Parse() method, passing as parameter the JSON string, as shown in the following sample:

Now you’re ready to execute some operations. Let’s take a look at the most common ones.

Simple JSON

Here is an example of a simple JSON file:

With LINQ to JSON, we are able to extract a single property’s value in the following way:

The JObject class is treated like a collection, so you can simply access a property using its name as a key. In the end, you can extract the value by using the Value<T>() method, where T is the data type we expect to be stored.

Complex JSON

Like C# objects, JSON objects can also have complex properties, as shown in the following sample:

Address is a complex property because it contains other nested properties. To access these properties, we need to use the SelectToken() method, passing the full JSON path as a parameter:

With the Address.City path, we are able to extract the value of the City property that is part of the Address node.

JSON Collections

When you handle JSON collections, you can use the Children() method to get access to all the children nodes of a specific property. Let’s use, as an example, a JSON code that we’ve previously seen:

In this case, we can use the JArray class and the Children() method to extract all the collection’s elements. In the following sample you can see how we use it to get a subcollection with only the Name property’s values.

Background Transfers

The HttpClient class we’ve previously seen, like the WebClient and HttpWebRequest classes, can be used only for foreground operations. When the application is suspended, network transfers are canceled.

When we have to deal with big data transfers, forcing the user to keep the app opened doesn’t create the best user experience. For this scenario, Windows Phone 7.5 has introduced background transfer APIs that can be used to start a download or upload operation and to continue it even if the app is suspended.

However, there are some limitations that have been introduced to avoid battery issues and high data plan consumption:

  • If the phone is connected to a cellular network, files bigger than 20 MB cannot be downloaded.
  • If the phone is connected to a Wi-Fi network, files bigger than 100 MB can’t be downloaded.
  • The 100 MB limit can be exceeded only if the phone is connected to a Wi-Fi network and the battery is charging.
  • A single application can queue up to 25 background transfer operations.
  • The global operating system’s queue can contain up to 500 background transfer operations.
  • The phone can execute a maximum of two transfer operations at a time.

A background transfer is identified by the BackgroundTransferRequest class, which is part of the Microsoft.Phone.BackgroundTransfer namespace. As developers, we have control over some conditions that need to be satisfied for a background transfer created in our application to start, thanks to the TransferPreferences property that can get the following values:

  • None, the default value: The transfer is started only if the phone is connected to a Wi-Fi network and the battery is charging.
  • AllowBattery: The transfer is started only if the phone is connected to a Wi‑Fi network, regardless of the power source.
  • AllowCelullar: The transfer is started only if the phone is charging, regardless of the network connection.

AllowCellularAndBattery: Always starts the transfer, regardless of the connection and power source conditions.

The BackgroundTransferRequest class exposes two event handlers that can be used to control the transfer:

  • TransferStatusChanged is triggered when the transfer’s status changes. The parameter returned by the method contains a TransferStatus object that notifies you of the current status (like Completed when the transfer ends, or Paused when the transfer is paused). There are also specific statuses that start with the Waiting prefix that tell you when a transfer is suspended because the conditions defined in the TransferPreferences property are not satisfied. For example, WaitingForWiFi is set when the transfer is waiting for the phone to be connected to a Wi-Fi network to start.
  • TransferProgressChanged is triggered when a transfer’s progress changes, meaning that new data has been downloaded or uploaded. Usually, this event handler is connected to a ProgressBar control since it exposes properties to notify you how much data has been transferred and how much data still needs to be downloaded or sent.

After you’ve defined a background transfer, you need to add it to the operating system’s queue. Windows Phone will take care of starting it when the specified conditions are satisfied. To accomplish this task, we use the BackgroundTransferService class, which is the central background transfer manager. You can add, remove, or list background transfers that belong to the application.

In the following sample you can see a background transfer definition:

We register this transfer to be executed regardless of the available network connection and power source. The previous sample is related to a download operation, so we need to define a source URI (the file to download) and a destination URI (the local storage path where the file will be saved). Unlike what we’ve seen with HttpClient, we don’t have to take care of the saving process; the file will be automatically downloaded and saved in the local storage since the download can also finish when the app is suspended. Both source and destination URIs are passed as parameters of the BackgroundTransferRequest constructor.

Note: Background transfers that are used to perform download operations always have to save the file inside the Shared/Transfers path in the local storage, which is automatically created when the app is installed—otherwise you’ll get an exception. When the download is complete, you are free to move the file to another position if needed, but you can’t schedule a background transfer that tries to download a file in a different folder.

Next, we subscribe to the TransferStatusChanged event. If the download is completed while the app is in the foreground, we are able to manage the downloaded file—for example, if it’s an image, we can display it. Notice the Remove() operation that we perform on the BackgroundTransferService class. It’s really important to always perform this task because the operating system won’t automatically remove completed transfers from the application’s queue and it can lead to unexpected issues since an application can’t schedule more than 25 transfers.

Instead, if you need to upload a file, you’ll need to create a BackgroundTransferRequest object in a different way. You still need to define two URIs: the source (the file to upload) and the destination (a service that is able to receive the file using the HTTP command set in the Method property). The destination URI can be passed in the BackgroundTransferRequest’s constructor (like we did previously), but the source URI needs to be set in the UploadLocation property, like in the following sample:

Conclusion

In this article we’ve seen how to work with one of the most used features of a smartphone: an Internet connection. In detail, we’ve learned:

  • Even if an Internet connection is a must-have for every device, we should be aware that sometimes users may not have an available connection. It’s important to properly check whether the phone is connected to the Internet before doing any network operation.
  • HttpClient is a new class introduced in Windows Runtime that helps perform network operations. We’ve seen how to use it to download and upload files, and interact with services.
  • Downloading and uploading files is a common task, but nowadays more and more applications have to interact with web services to get the data they need. In this article we’ve learned how, thanks to the JSON.NET library, it’s easy to work with REST services and convert JSON data into C# objects.
  • HttpClient is a great help, but it works only if the application is in the foreground. When it’s suspended, network operations are canceled. For this purpose, the framework offers some specific APIs to perform download and upload operations even in the background when the app is not in use.

This tutorial represents a chapter from Windows Phone 8 Succinctly, a free eBook from the team at Syncfusion.

2015-03-19T12:43:38.000Z2015-03-19T12:43:38.000ZMatteo Pagani

Windows Phone 8 Succinctly: Data Access—Network

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

Checking the Internet Connection

All Windows Phone devices have a built-in network connection but, for the same reason we learned how to locally store data, we need to be ready to manage how users are using our application while a connection is missing.

For this purpose, the Windows Phone framework includes a class that can be used to discover information about the Internet connection called DeviceNetworkInformation, which is part of the Microsoft.Phone.Net.NetworkInformation namespace.

The most important one is IsNetworkAvailable, which tells us whether an Internet connection is available. We should always use this API before performing an operation that requires a connection, like the following sample:

The class also offers an event called NetworkAvailabilityChanged which is triggered every time the connection status changes. It’s useful if you want to quickly react to network changes, such as enabling or disabling certain application features.

The return parameters contain a property called NotificationType, of the type NetworkNotificationType, which tells us the current network status.

However, with the DeviceNetworkInformation you’ll be able to also get other information about the current network status, like whether the user has enabled the cellular data connection (IsCellularDataEnabled), the Wi-Fi connection (IsWiFiEnabled), or roaming options (IsCellularDataRoamingOptions).

The framework offers another useful class to deal with network connections called NetworkInterface. By using the NetworkInterfaceType property, you’ll be able to identify which connection type is currently in use. For example, we can use this property to avoid downloading big files while using a cellular connection.

NetworkInterfaceType is an enumerator that can assume many values. The most important ones are:

  • MobileBroadbandGsm and MobileBroadbandCdma when the phone is connected to a cellular network (GSM or CDMA, according to the country)
  • Wireless80211, when the phone is connected to a Wi-Fi network

In the following sample, we display a message on the screen with the current connection type:

Performing Network Operations: HttpClient

The Windows Phone framework has two built-in classes for performing network operations: WebClient and HttpWebRequest. Unfortunately, neither of them is perfect. WebClient is very easy to use, but it’s based on the old callback approach (unless you install the Async for .NET package we discussed earlier in this series). HttpWebRequest is very powerful, but it is complex to use and based on an old asynchronous pattern that is hard to understand.

The Windows Runtime has introduced a new class called HttpClient, which takes the best of both worlds. It’s powerful and offers great performance, but it’s easy to use and offers methods that are based on the new async and await pattern. This class is available in the full Windows Runtime for Windows Store apps, but it’s not included in the Windows Phone Runtime subset—you’ll have to install it from NuGet.

The HttpClient class, as we’ll see later, is great not just for performing generic network operations like downloading and uploading file, but also for interacting with web services. In fact, it exposes asynchronous methods for every HTTP command, like GET, POST, PUT, etc.

Note: To be able to interact with the network you’ll have to enable the ID_CAP_NETWORKING option in the manifest file. It is enabled in every new Windows Phone project by default.

Downloading Data

Files are usually downloaded using the GET HTTP command, so HttpClient offers the GetAsync() method. To make developers’ lives simpler, HttpClient has some built-in methods to download the most common file types, such as GetStringAsync() for downloading text files like XML, RSS, or REST responses; or GetByteArrayAsync() and GetStreamAsync() to get binary file content.

Downloading strings is really easy. The method GetStringAsync() requires as a parameter the file’s URL and returns the file’s content as a string. In the following sample, you can see how to download my blog’s RSS feed:

Once you have the string, you can perform the required operations according to your scenario. For example, in the previous sample I could have parsed the returned XML with LINQ to XML to display the news list on the screen.

Downloading binary files can be accomplished in many ways. You can use GetByteArrayAsync() if you prefer to work with bytes, or GetStreamAsync() if you prefer to manipulate the file’s content as a stream.

In the following sample, you’ll see how to download a picture using the GetByteArrayAsync() method. It returns a byte’s array, which can be easily saved in the local storage using the APIs we learned about earlier in this series.

By using the DataWriter class, we’re able to save the byte array returned by the HttpClient class into a file in the local storage called picture.png.

If you need full control over the download operation, you can use the generic GetAsync() method, which returns a HttpResponseMessage object with the entire response’s content, like headers, status code, etc.

In the following sample you can see how, by using the GetAsync() method, we’re able to download a picture as a Stream and display it in an Image control placed on the page. To the method we pass a second parameter of type HttpCompletionOption, which tells the class when to mark the operation as completed. Since we want the full content of the response (which is the downloaded image), we use the ResponseContentRead option.

Notice that the specific methods we’ve seen offered by the HttpClient class are simply a shortcut to the methods offered by the Content property of the HttpResponseMessage class (in the previous sample, we use the ReadAsStreamAsync() method to return the response’s content as a Stream).

Uploading Data

Uploading data is accomplished in a similar way: the operation is usually performed using the POST command, so the HttpClient class exposes the PostAsync() method for this purpose.

The content to send is prepared using the HttpContent class, which offers many implementations: StreamContent to send a file’s stream, ByteArrayContent to send a binary file, StringContent to send a string, or MultipartFormDataContent to send content encoded using multipart/form-data MIME type.

In the following sample, you can see how to upload a file’s stream to a service:

After we have retrieved the stream of a file stored in the local storage, we pass it to a new instance of the StreamContent class. Then, we call the PostAsync() method, passing the service’s URL and the HttpContent object as parameters.

Using REST Services

REST (Representational State Transfer) is, without a doubt, the most used approach nowadays in web service development, especially in the mobile world.

REST services have become very popular for two reasons:

  • They are based on the HTTP protocol and they expose operations using the standard HTTP commands (like GET, POST, PUT, etc.).
  • They return data using standard languages like XML and JSON.

Almost every platform natively supports these technologies, so you don’t have to look for special libraries to interact with them as is needed for WSDL-based web services.

We’ve already seen how, with the HttpClient class, it’s simple to interact with the web by using the standard HTTP commands. Most of the time, to interact with a REST service, you’ll simply have to execute the GetStringAsync() method to get the XML or JSON response.

Once you have the result, most of the time you’ll have to convert it into objects to be used inside the application. Earlier in this series, we discussed the easiest way to accomplish this task: deserialization, which means translating plain text into complex objects. We can use the DataContractSerializer or DataContractJsonSerializer classes to do this. In this case, you just have to refer to the deserialization process since the procedure is the same.

We assume that the service returns, in JSON format, a list of persons:

With the help of the DataContractJsonSerializer class, we are able to convert the previous JSON into a list of Person objects, which is the same class we have used in many other samples in this series. The difference in this sample is that we are able to control the serialization process, in case, for example, the property names returned from the JSON are different than the ones we use in our classes. This is a very common scenario when dealing with JSON since property names are typically lowercase, while in C# objects they are CamelCase. This result is achieved by using the [DataMember] attribute, which can be applied to the properties we want to serialize. In the following sample, you can see that the attribute offers a property called Name, which can be used to specify which property name we expect to find in the JSON file.

This approach has a downside: REST services always return a plain string, while the DataContractJsonSerializer class requires a Stream as an input parameter of the ReadObject() method, so we’re always forced to convert it using a MemoryStream object.

There is another way to accomplish the same result. Let me introduce JSON.NET, a third-party library that offers some additional useful features for handling JSON data. In addition, it offers better performance and is able to deserialize complex JSON files quicker.

It can be easily installed using NuGet, and its official website offers comparisons with other JSON libraries and detailed documentation.

In the following sample, we use JSON.NET to achieve the same result as the code that we’ve previously used:

The JsonConvert class (which is part of the Newtonsoft.Json namespace) exposes the DeserializeObject<T>() method, where T is the object’s type we expect in return. As an input parameter, it requires only the JSON string that we’ve downloaded from the service.

It’s also possible to control the deserialization process using attributes, like we previously did with the DataMember attribute. In the following sample, you can see how we can manually define how JSON properties should be translated:

Tip: You will often have to use third-party services, so you won’t know the exact mapping between entities and JSON data. There is a website that will help you in this scenario: http://json2csharp.com/. Simply paste the JSON returned by your service, and it will generate for you the needed C# classes to map the JSON data. 

LINQ to JSON

Another interesting feature introduced by JSON.NET is LINQ to JSON, which is a LINQ-based language that, similar to LINQ to XML, can be used to manipulate a JSON string to extract just the information you need. This approach is useful when you do not really need to use deserialization, but just need to extract some data from the JSON response you received from the service.

The starting point to use LINQ to JSON is the JObject class, which identifies a JSON file. To start working with it, you simply have to call the Parse() method, passing as parameter the JSON string, as shown in the following sample:

Now you’re ready to execute some operations. Let’s take a look at the most common ones.

Simple JSON

Here is an example of a simple JSON file:

With LINQ to JSON, we are able to extract a single property’s value in the following way:

The JObject class is treated like a collection, so you can simply access a property using its name as a key. In the end, you can extract the value by using the Value<T>() method, where T is the data type we expect to be stored.

Complex JSON

Like C# objects, JSON objects can also have complex properties, as shown in the following sample:

Address is a complex property because it contains other nested properties. To access these properties, we need to use the SelectToken() method, passing the full JSON path as a parameter:

With the Address.City path, we are able to extract the value of the City property that is part of the Address node.

JSON Collections

When you handle JSON collections, you can use the Children() method to get access to all the children nodes of a specific property. Let’s use, as an example, a JSON code that we’ve previously seen:

In this case, we can use the JArray class and the Children() method to extract all the collection’s elements. In the following sample you can see how we use it to get a subcollection with only the Name property’s values.

Background Transfers

The HttpClient class we’ve previously seen, like the WebClient and HttpWebRequest classes, can be used only for foreground operations. When the application is suspended, network transfers are canceled.

When we have to deal with big data transfers, forcing the user to keep the app opened doesn’t create the best user experience. For this scenario, Windows Phone 7.5 has introduced background transfer APIs that can be used to start a download or upload operation and to continue it even if the app is suspended.

However, there are some limitations that have been introduced to avoid battery issues and high data plan consumption:

  • If the phone is connected to a cellular network, files bigger than 20 MB cannot be downloaded.
  • If the phone is connected to a Wi-Fi network, files bigger than 100 MB can’t be downloaded.
  • The 100 MB limit can be exceeded only if the phone is connected to a Wi-Fi network and the battery is charging.
  • A single application can queue up to 25 background transfer operations.
  • The global operating system’s queue can contain up to 500 background transfer operations.
  • The phone can execute a maximum of two transfer operations at a time.

A background transfer is identified by the BackgroundTransferRequest class, which is part of the Microsoft.Phone.BackgroundTransfer namespace. As developers, we have control over some conditions that need to be satisfied for a background transfer created in our application to start, thanks to the TransferPreferences property that can get the following values:

  • None, the default value: The transfer is started only if the phone is connected to a Wi-Fi network and the battery is charging.
  • AllowBattery: The transfer is started only if the phone is connected to a Wi‑Fi network, regardless of the power source.
  • AllowCelullar: The transfer is started only if the phone is charging, regardless of the network connection.

AllowCellularAndBattery: Always starts the transfer, regardless of the connection and power source conditions.

The BackgroundTransferRequest class exposes two event handlers that can be used to control the transfer:

  • TransferStatusChanged is triggered when the transfer’s status changes. The parameter returned by the method contains a TransferStatus object that notifies you of the current status (like Completed when the transfer ends, or Paused when the transfer is paused). There are also specific statuses that start with the Waiting prefix that tell you when a transfer is suspended because the conditions defined in the TransferPreferences property are not satisfied. For example, WaitingForWiFi is set when the transfer is waiting for the phone to be connected to a Wi-Fi network to start.
  • TransferProgressChanged is triggered when a transfer’s progress changes, meaning that new data has been downloaded or uploaded. Usually, this event handler is connected to a ProgressBar control since it exposes properties to notify you how much data has been transferred and how much data still needs to be downloaded or sent.

After you’ve defined a background transfer, you need to add it to the operating system’s queue. Windows Phone will take care of starting it when the specified conditions are satisfied. To accomplish this task, we use the BackgroundTransferService class, which is the central background transfer manager. You can add, remove, or list background transfers that belong to the application.

In the following sample you can see a background transfer definition:

We register this transfer to be executed regardless of the available network connection and power source. The previous sample is related to a download operation, so we need to define a source URI (the file to download) and a destination URI (the local storage path where the file will be saved). Unlike what we’ve seen with HttpClient, we don’t have to take care of the saving process; the file will be automatically downloaded and saved in the local storage since the download can also finish when the app is suspended. Both source and destination URIs are passed as parameters of the BackgroundTransferRequest constructor.

Note: Background transfers that are used to perform download operations always have to save the file inside the Shared/Transfers path in the local storage, which is automatically created when the app is installed—otherwise you’ll get an exception. When the download is complete, you are free to move the file to another position if needed, but you can’t schedule a background transfer that tries to download a file in a different folder.

Next, we subscribe to the TransferStatusChanged event. If the download is completed while the app is in the foreground, we are able to manage the downloaded file—for example, if it’s an image, we can display it. Notice the Remove() operation that we perform on the BackgroundTransferService class. It’s really important to always perform this task because the operating system won’t automatically remove completed transfers from the application’s queue and it can lead to unexpected issues since an application can’t schedule more than 25 transfers.

Instead, if you need to upload a file, you’ll need to create a BackgroundTransferRequest object in a different way. You still need to define two URIs: the source (the file to upload) and the destination (a service that is able to receive the file using the HTTP command set in the Method property). The destination URI can be passed in the BackgroundTransferRequest’s constructor (like we did previously), but the source URI needs to be set in the UploadLocation property, like in the following sample:

Conclusion

In this article we’ve seen how to work with one of the most used features of a smartphone: an Internet connection. In detail, we’ve learned:

  • Even if an Internet connection is a must-have for every device, we should be aware that sometimes users may not have an available connection. It’s important to properly check whether the phone is connected to the Internet before doing any network operation.
  • HttpClient is a new class introduced in Windows Runtime that helps perform network operations. We’ve seen how to use it to download and upload files, and interact with services.
  • Downloading and uploading files is a common task, but nowadays more and more applications have to interact with web services to get the data they need. In this article we’ve learned how, thanks to the JSON.NET library, it’s easy to work with REST services and convert JSON data into C# objects.
  • HttpClient is a great help, but it works only if the application is in the foreground. When it’s suspended, network operations are canceled. For this purpose, the framework offers some specific APIs to perform download and upload operations even in the background when the app is not in use.

This tutorial represents a chapter from Windows Phone 8 Succinctly, a free eBook from the team at Syncfusion.

2015-03-19T12:43:38.000Z2015-03-19T12:43:38.000ZMatteo Pagani

Your First WatchKit Application: User Interface

$
0
0

Last week, Apple announced the release date for Apple Watch. The company also released Xcode 6.2, which includes support for Apple Watch. With Xcode 6.2, you have everything you need to create your first application for Apple Watch.

With the Apple Watch release date set for April, it is time to learn the ropes of Apple Watch development. In this tutorial, you will create your first WatchKit application. Along the way, you will become familiar with the inner workings of a WatchKit application and find out that there are many similarities with iOS development.

Prerequisites

Because this tutorial focuses on Apple Watch development, I assume that you're already familiar with the basics of iOS development. If you don't know what actions and outlets are, for example, I recommend you first take our introductory course on iOS development.

To follow along, you need to have Xcode 6.2 or higher installed on your development machine. You can download Xcode from the iOS Dev Center or the Mac App Store. As I mentioned earlier, Xcode 6.2 includes support for Apple Watch. Without Xcode 6.2, you won't be able to follow along.

In this tutorial, I will be using Swift as the programming language. If you're not familiar with Swift, then you have two options. Your first option is to stick with Objective-C. You can create Apple Watch applications with both Swift and Objective-C, or a combination of the two. Your second option is to stop here and read my series on Swift or watch Derek Jensen's course on Swift development.

1. Introduction

You may be wondering what the difference is between an Apple Watch application and a WatchKit application. Last year, Apple announced that there will be two generations of Apple Watch applications, WatchKit applications and native Apple Watch applications. The term native is a bit misleading since WatchKit applications are also native applications. The main difference is the application architecture. Let's look at native applications first.

Native Applications

Apple hasn't told us much about native applications yet. The company only announced that native applications will arrive on Apple Watch in the fall of this year. It's unclear what the SDK will look like and what developers will be able to do with a native Apple Watch application. In other words, we have no choice but to focus on WatchKit applications for the time being.

That said, based on Apple's information, the main difference will be that native applications will be able to run without an extension running on a paired iPhone. From an architectural point of view, native application will resemble native iOS applications on iPhone and iPad.

WatchKit Applications

As the name implies, a WatchKit application completely relies on the WatchKit framework to do its work. The WatchKit framework is a nifty solution that bridges the gap between the Apple Watch and a paired iPhone.

While the idea is simple, the implementation is less so. The WatchKit application runs on the Apple Watch and is in charge of two things:

  • presenting the user interface
  • responding to user interaction

The business logic and heavy lifting is taken care of by a Apple Watch extension running on a paired iPhone. The following diagram visualizes the role of the WatchKit framework.

Any events triggered by the user interacting with the WatchKit application are forwarded to the extension that runs on the paired iPhone. This implies that the WatchKit application is of no use without a paired iPhone. It simply cannot do its work without the extension running on an iPhone.

2. Project Setup

With this in mind, it's time to create your first WatchKit application. The application we're about to create will show the user the weather conditions of various places on the planet. It's the equivalent of the weather application on iOS.

Step 1: Create Project

Launch Xcode and select New > Project... from the File menu. Select the Single View Application template from the list of iOS > Application templates. You may be wondering why we're not creating a WatchKit application. A WatchKit application is always part of an iOS application. This will become clearer once we've added the WatchKit application to the project.

Name your application RainDrop, set Language to Swift, and Devices to iPhone. Make sure Use Core Data is unchecked.

Tell Xcode where you'd like to save the project files and hit Create. Note that we've created a plain vanilla Xcode project for a single view iOS application. If you build and run the RainDrop target in the iOS Simulator, you'll see a white view. This is what we expect from an iOS application based on the Single View Application template.

Before we continue, take a good look at the project structure in the Project Navigator and the list of targets. We currently have two targets, RainDrop, for the iOS application and RainDropTests, for the tests of the RainDrop target. Let's add a WatchKit application to the mix.

Step 2: Create WatchKit Targets

Select New > Target... from Xcode's File menu and choose WatchKit App from the iOS > Apple Watch section on the left.

For the purpose of this tutorial, uncheck Include Notification Scene and Include Glance Scene. We won't be covering notifications and glances in this tutorial. Hit Finish in the lower right to add the WatchKit application to your Xcode project.

When you click Finish, Xcode will create a number of files, groups, and targets. Xcode will also create a scheme to run the WatchKit application in the iOS Simulator and it will ask you whether it should activate that scheme. Click Activate to activate it.

3. Project Anatomy

By adding a WatchKit application to our project, Xcode has created two targets for us, one for the WatchKit extension, RainDrop WatchKit Extension, and one for the WatchKit application, RainDrop WatchKit App.

The WatchKit extension will run on the iPhone paired to the Apple Watch. It is in charge of the business logic of the WatchKit application. The WatchKit application will run on the Apple Watch and will be responsible for presenting the user interface and handling events.

To keep everything nice and tidy, Xcode has created two groups for us in the Project Navigator. The first group, RainDrop WatchKit Extension, contains the source files and assets for the WatchKit extension. The second group, RainDrop WatchKit App, contains the assets for the WatchKit application.

The underlying architecture of a WatchKit application is evident based on the contents of these groups. The RainDrop WatchKit App group, for example, doesn't contain any source files. It only includes a storyboard and assets for the user interface of the WatchKit application. The RainDrop WatchKit Extension contains one source file, InterfaceController.swift, but it doesn't include a storyboard. This makes sense if you remember that the extension is in charge of the business logic of the WatchKit application while the WatchKit application is responsible for the user interface.

Apple uses the term application for several concepts. It's important that you understand that a WatchKit application consists of two parts, a WatchKit extension running on a paired iPhone and a WatchKit application running on the Apple Watch. A WatchKit application cannot do its work without its extension. That is key to understand the architecture of a WatchKit application.

4. Build and Run

Before we build and run the WatchKit application, it's useful to understand what's going to happen when you hit Command-R. When Xcode has finished building the iOS application, the WatchKit extension, and the WatchKit application, it will install the iOS application, the WatchKit extension, and the WatchKit application on the iOS Simulator. It will then run the WatchKit extension and the WatchKit application in the iOS Simulator.

If you're not familiar with extensions, then you may be wondering why it installs the iOS application on the iOS Simulator. An extension is always associated with an iOS application so the iOS application is required for the WatchKit extension to run. Along the same lines, a WatchKit application can only run on an Apple Watch if its counterpart, the WatchKit extension, is running on an iPhone paired with the Apple Watch. It's a fairly complex architecture if you're used to developing standalone iOS applications.

When you press Command-R on your keyboard or click the Run button in the top left, Xcode will build and run your WatchKit application in the iOS Simulator. If the WatchKit application isn't launched, then double-check that you're using the correct scheme.

Running the WatchKit application isn't very spectacular since you only see a black screen with the current time in the top right. Let's make the user interface of our WatchKit application a bit more interesting.

5. Create the User Interface

Since you're reading this tutorial, I'm assuming you're familiar with iOS development. As you know, modern iOS development involves Auto Layout and storyboards. This is only partially true for WatchKit development. We already discovered that a WatchKit application uses a storyboard for its user interface. Auto Layout, however, is absent.

Open Interface.storyboard in the RainDrop WatchKit App group to find out how to build a user interface for our WatchKit application.

The storyboard contains a single scene, the Interface Controller Scene. In the Scene Navigator, on the right of the Project Navigator, you can see that the Interface Controller Scene includes an Interface Controller and an indication that this scene is the main entry point of our WatchKit application.

What Is an Interface Controller?

The two questions you're probably asking yourself are "What is an interface controller?" and "How does it differ from a view controller?" An interface controller is an instance of the WKInterfaceController class or a subclass thereof. The WKInterfaceController class is defined in the WatchKit framework.

The name of this class hints at the differences with UIViewController. As you know, a view controller controls a view or view hierarchy. An interface controller, however, doesn't control a view, instead it controls an interface, that is, a screenful of content. What this means will become clearer once we start implementing the interface controller.

An interface controller is still a true controller in that it controls the behavior of the user interface. With an interface controller, you can configure the user interface of your WatchKit application and respond to the events the WatchKit application forwards to the WatchKit extension. How this works will become clearer later in this tutorial.

Creating a Layout

The layout system WatchKit provides us with is primitive compared to the power and flexibility of Auto Layout. The layout system is reminiscent of how web pages are laid out with HTML and CSS.

One of the building blocks of the WatchKit layout system is the WKInterfaceGroup class. An instance of this class is nothing more than a container that can hold other interface elements, such as labels, tables, etc. You can compare it with a <div> element on a web page. It provides structure and determines the layout together with other groups of the layout.

From the Object Library on the right, add two groups to the interface controller as shown below.

Did you notice that the groups automatically snap into place? The layout system behaves very differently from Auto Layout. Another important detail is that the container of the interface controller is also a group, not a view. This means that you added the groups to another group. This is fine since groups can be nested, allowing developers to create fairly complex layouts for their WatchKit applications.

Adding Interface Elements

Add a label from the Object Library to the top group and see what happens. The size of the group decreases to fit the size of the label. The outline of an empty group is nothing more than a placeholder. A group will always adjust its size to that of its contents.

Select the label and open the Identity Inspector on the right. Note that the label you added is of type WKInterfaceLabel, not UILabel. Even though WatchKit applications can have many user interface elements that resemble those found in iOS applications, they are different. The WKInterfaceLabel class, for example, inherits from WKInterfaceObject instead of UIView and UIResponder.

With the label selected, open the Attributes Inspector on the right. Under Size, set width to Relative to Container to make it as wide as the screen of the Apple Watch. Change the font to Headline to make it stand out a bit more and change the label's text to Cupertino. Notice that you cannot change the font family nor can you manually adjust the font size.

Since our WatchKit application will be displaying the weather conditions of various places on the planet, we also need to add a label for the temperature. It would also be nice to know the local date and time of the location.

Add a second label to the top group by dragging a label in the Scene Navigator. Wait. That's not right. You've added a label to the correct group, but it isn't showing up in the interface.

By default, a group has a horizontal layout. You can verify this by opening the Attributes Inspector and inspecting its Layout property. This means that the interface elements it contains are laid out horizontally. The temperature label is present in the group, but it's not visible at the moment. Change the group's Layout property to Vertical to resolve the issue.

Add a Date interface element to the second group. Date interface elements are instances of the WKInterfaceDate class. This interface element contains a label and is perfect for displaying and formatting dates. Start by changing the element's width to Relative to Container and the label's text alignment to right aligned.

There's no need to use the NSDateFormatter class to format dates. The WKInterfaceDate class handles date formatting for us. Change the Format of the WKInterfaceDate instance to Custom and set the format to M/d, h:mm a. The user interface should now look like this.

Build and run the WatchKit application in the iOS Simulator to see what we've got so far. The application isn't very useful at the moment since we're working with static content. We'll fix this in the next tutorial.

Conclusion

We've covered the very basics of WatchKit application development in this tutorial. I'm sure you agree that developing WatchKit applications feels both familiar and foreign. We can use the tools we're accustomed to, but there are a number of key differences that will take time to get comfortable with. In the second part of this tutorial, we will focus on the WatchKit extension to fetch weather data and display that data in the WatchKit application.

2015-03-20T18:15:08.000Z2015-03-20T18:15:08.000ZBart Jacobs

Your First WatchKit Application: User Interface

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

Last week, Apple announced the release date for Apple Watch. The company also released Xcode 6.2, which includes support for Apple Watch. With Xcode 6.2, you have everything you need to create your first application for Apple Watch.

With the Apple Watch release date set for April, it is time to learn the ropes of Apple Watch development. In this tutorial, you will create your first WatchKit application. Along the way, you will become familiar with the inner workings of a WatchKit application and find out that there are many similarities with iOS development.

Prerequisites

Because this tutorial focuses on Apple Watch development, I assume that you're already familiar with the basics of iOS development. If you don't know what actions and outlets are, for example, I recommend you first take our introductory course on iOS development.

To follow along, you need to have Xcode 6.2 or higher installed on your development machine. You can download Xcode from the iOS Dev Center or the Mac App Store. As I mentioned earlier, Xcode 6.2 includes support for Apple Watch. Without Xcode 6.2, you won't be able to follow along.

In this tutorial, I will be using Swift as the programming language. If you're not familiar with Swift, then you have two options. Your first option is to stick with Objective-C. You can create Apple Watch applications with both Swift and Objective-C, or a combination of the two. Your second option is to stop here and read my series on Swift or watch Derek Jensen's course on Swift development.

1. Introduction

You may be wondering what the difference is between an Apple Watch application and a WatchKit application. Last year, Apple announced that there will be two generations of Apple Watch applications, WatchKit applications and native Apple Watch applications. The term native is a bit misleading since WatchKit applications are also native applications. The main difference is the application architecture. Let's look at native applications first.

Native Applications

Apple hasn't told us much about native applications yet. The company only announced that native applications will arrive on Apple Watch in the fall of this year. It's unclear what the SDK will look like and what developers will be able to do with a native Apple Watch application. In other words, we have no choice but to focus on WatchKit applications for the time being.

That said, based on Apple's information, the main difference will be that native applications will be able to run without an extension running on a paired iPhone. From an architectural point of view, native application will resemble native iOS applications on iPhone and iPad.

WatchKit Applications

As the name implies, a WatchKit application completely relies on the WatchKit framework to do its work. The WatchKit framework is a nifty solution that bridges the gap between the Apple Watch and a paired iPhone.

While the idea is simple, the implementation is less so. The WatchKit application runs on the Apple Watch and is in charge of two things:

  • presenting the user interface
  • responding to user interaction

The business logic and heavy lifting is taken care of by a Apple Watch extension running on a paired iPhone. The following diagram visualizes the role of the WatchKit framework.

Any events triggered by the user interacting with the WatchKit application are forwarded to the extension that runs on the paired iPhone. This implies that the WatchKit application is of no use without a paired iPhone. It simply cannot do its work without the extension running on an iPhone.

2. Project Setup

With this in mind, it's time to create your first WatchKit application. The application we're about to create will show the user the weather conditions of various places on the planet. It's the equivalent of the weather application on iOS.

Step 1: Create Project

Launch Xcode and select New > Project... from the File menu. Select the Single View Application template from the list of iOS > Application templates. You may be wondering why we're not creating a WatchKit application. A WatchKit application is always part of an iOS application. This will become clearer once we've added the WatchKit application to the project.

Name your application RainDrop, set Language to Swift, and Devices to iPhone. Make sure Use Core Data is unchecked.

Tell Xcode where you'd like to save the project files and hit Create. Note that we've created a plain vanilla Xcode project for a single view iOS application. If you build and run the RainDrop target in the iOS Simulator, you'll see a white view. This is what we expect from an iOS application based on the Single View Application template.

Before we continue, take a good look at the project structure in the Project Navigator and the list of targets. We currently have two targets, RainDrop, for the iOS application and RainDropTests, for the tests of the RainDrop target. Let's add a WatchKit application to the mix.

Step 2: Create WatchKit Targets

Select New > Target... from Xcode's File menu and choose WatchKit App from the iOS > Apple Watch section on the left.

For the purpose of this tutorial, uncheck Include Notification Scene and Include Glance Scene. We won't be covering notifications and glances in this tutorial. Hit Finish in the lower right to add the WatchKit application to your Xcode project.

When you click Finish, Xcode will create a number of files, groups, and targets. Xcode will also create a scheme to run the WatchKit application in the iOS Simulator and it will ask you whether it should activate that scheme. Click Activate to activate it.

3. Project Anatomy

By adding a WatchKit application to our project, Xcode has created two targets for us, one for the WatchKit extension, RainDrop WatchKit Extension, and one for the WatchKit application, RainDrop WatchKit App.

The WatchKit extension will run on the iPhone paired to the Apple Watch. It is in charge of the business logic of the WatchKit application. The WatchKit application will run on the Apple Watch and will be responsible for presenting the user interface and handling events.

To keep everything nice and tidy, Xcode has created two groups for us in the Project Navigator. The first group, RainDrop WatchKit Extension, contains the source files and assets for the WatchKit extension. The second group, RainDrop WatchKit App, contains the assets for the WatchKit application.

The underlying architecture of a WatchKit application is evident based on the contents of these groups. The RainDrop WatchKit App group, for example, doesn't contain any source files. It only includes a storyboard and assets for the user interface of the WatchKit application. The RainDrop WatchKit Extension contains one source file, InterfaceController.swift, but it doesn't include a storyboard. This makes sense if you remember that the extension is in charge of the business logic of the WatchKit application while the WatchKit application is responsible for the user interface.

Apple uses the term application for several concepts. It's important that you understand that a WatchKit application consists of two parts, a WatchKit extension running on a paired iPhone and a WatchKit application running on the Apple Watch. A WatchKit application cannot do its work without its extension. That is key to understand the architecture of a WatchKit application.

4. Build and Run

Before we build and run the WatchKit application, it's useful to understand what's going to happen when you hit Command-R. When Xcode has finished building the iOS application, the WatchKit extension, and the WatchKit application, it will install the iOS application, the WatchKit extension, and the WatchKit application on the iOS Simulator. It will then run the WatchKit extension and the WatchKit application in the iOS Simulator.

If you're not familiar with extensions, then you may be wondering why it installs the iOS application on the iOS Simulator. An extension is always associated with an iOS application so the iOS application is required for the WatchKit extension to run. Along the same lines, a WatchKit application can only run on an Apple Watch if its counterpart, the WatchKit extension, is running on an iPhone paired with the Apple Watch. It's a fairly complex architecture if you're used to developing standalone iOS applications.

When you press Command-R on your keyboard or click the Run button in the top left, Xcode will build and run your WatchKit application in the iOS Simulator. If the WatchKit application isn't launched, then double-check that you're using the correct scheme.

Running the WatchKit application isn't very spectacular since you only see a black screen with the current time in the top right. Let's make the user interface of our WatchKit application a bit more interesting.

5. Create the User Interface

Since you're reading this tutorial, I'm assuming you're familiar with iOS development. As you know, modern iOS development involves Auto Layout and storyboards. This is only partially true for WatchKit development. We already discovered that a WatchKit application uses a storyboard for its user interface. Auto Layout, however, is absent.

Open Interface.storyboard in the RainDrop WatchKit App group to find out how to build a user interface for our WatchKit application.

The storyboard contains a single scene, the Interface Controller Scene. In the Scene Navigator, on the right of the Project Navigator, you can see that the Interface Controller Scene includes an Interface Controller and an indication that this scene is the main entry point of our WatchKit application.

What Is an Interface Controller?

The two questions you're probably asking yourself are "What is an interface controller?" and "How does it differ from a view controller?" An interface controller is an instance of the WKInterfaceController class or a subclass thereof. The WKInterfaceController class is defined in the WatchKit framework.

The name of this class hints at the differences with UIViewController. As you know, a view controller controls a view or view hierarchy. An interface controller, however, doesn't control a view, instead it controls an interface, that is, a screenful of content. What this means will become clearer once we start implementing the interface controller.

An interface controller is still a true controller in that it controls the behavior of the user interface. With an interface controller, you can configure the user interface of your WatchKit application and respond to the events the WatchKit application forwards to the WatchKit extension. How this works will become clearer later in this tutorial.

Creating a Layout

The layout system WatchKit provides us with is primitive compared to the power and flexibility of Auto Layout. The layout system is reminiscent of how web pages are laid out with HTML and CSS.

One of the building blocks of the WatchKit layout system is the WKInterfaceGroup class. An instance of this class is nothing more than a container that can hold other interface elements, such as labels, tables, etc. You can compare it with a <div> element on a web page. It provides structure and determines the layout together with other groups of the layout.

From the Object Library on the right, add two groups to the interface controller as shown below.

Did you notice that the groups automatically snap into place? The layout system behaves very differently from Auto Layout. Another important detail is that the container of the interface controller is also a group, not a view. This means that you added the groups to another group. This is fine since groups can be nested, allowing developers to create fairly complex layouts for their WatchKit applications.

Adding Interface Elements

Add a label from the Object Library to the top group and see what happens. The size of the group decreases to fit the size of the label. The outline of an empty group is nothing more than a placeholder. A group will always adjust its size to that of its contents.

Select the label and open the Identity Inspector on the right. Note that the label you added is of type WKInterfaceLabel, not UILabel. Even though WatchKit applications can have many user interface elements that resemble those found in iOS applications, they are different. The WKInterfaceLabel class, for example, inherits from WKInterfaceObject instead of UIView and UIResponder.

With the label selected, open the Attributes Inspector on the right. Under Size, set width to Relative to Container to make it as wide as the screen of the Apple Watch. Change the font to Headline to make it stand out a bit more and change the label's text to Cupertino. Notice that you cannot change the font family nor can you manually adjust the font size.

Since our WatchKit application will be displaying the weather conditions of various places on the planet, we also need to add a label for the temperature. It would also be nice to know the local date and time of the location.

Add a second label to the top group by dragging a label in the Scene Navigator. Wait. That's not right. You've added a label to the correct group, but it isn't showing up in the interface.

By default, a group has a horizontal layout. You can verify this by opening the Attributes Inspector and inspecting its Layout property. This means that the interface elements it contains are laid out horizontally. The temperature label is present in the group, but it's not visible at the moment. Change the group's Layout property to Vertical to resolve the issue.

Add a Date interface element to the second group. Date interface elements are instances of the WKInterfaceDate class. This interface element contains a label and is perfect for displaying and formatting dates. Start by changing the element's width to Relative to Container and the label's text alignment to right aligned.

There's no need to use the NSDateFormatter class to format dates. The WKInterfaceDate class handles date formatting for us. Change the Format of the WKInterfaceDate instance to Custom and set the format to M/d, h:mm a. The user interface should now look like this.

Build and run the WatchKit application in the iOS Simulator to see what we've got so far. The application isn't very useful at the moment since we're working with static content. We'll fix this in the next tutorial.

Conclusion

We've covered the very basics of WatchKit application development in this tutorial. I'm sure you agree that developing WatchKit applications feels both familiar and foreign. We can use the tools we're accustomed to, but there are a number of key differences that will take time to get comfortable with. In the second part of this tutorial, we will focus on the WatchKit extension to fetch weather data and display that data in the WatchKit application.

2015-03-20T18:15:08.000Z2015-03-20T18:15:08.000ZBart Jacobs

Getting Started With RecyclerView and CardView on Android

$
0
0

If you are interested in building an Android app that makes use of lists to display data, Android Lollipop features two new widgets to make your life easier, RecyclerView and CardView. Using these widgets, it is very easy to give your app a look and feel that conforms to the guidelines mentioned in Google's material design specification.

Prerequisites

To follow along, you should be using the latest version of Android Studio. You can get it from the Android Developer website.

1. Support Older Versions

At the time of writing, less than 2% of Android devices run Android Lollipop. However, thanks to the v7 Support Library, you can use the RecyclerView and CardView widgets on devices that run older versions of Android by adding the following lines to the dependencies section in your project's build.grade file:

2. Creating a CardView

A CardView is a ViewGroup. Like any other ViewGroup, it can be added to your Activity or Fragment using a layout XML file.

To create an empty CardView, you would have to add the following code to your layout XML as shown in the following snippet:

As a more realistic example, let us now create a LinearLayout and place a CardView inside it. The CardView could represent, for example, a person and contain the following:

  • TextView to display the name of the person
  • TextView to display the person's age
  • an ImageView to display the person's photo

This is what the XML would look like:

If this XML is used as the layout of an Activity, with the TextView and ImageView fields are set to meaningful values, then this is how it would render on an Android device:

A Stand-alone Card

3. Creating a RecyclerView

Step 1: Defining It in a Layout

Using a RecyclerView instance is slightly more complicated. However, defining it in a layout XML file is quite simple. You can define it in a layout as follows:

To obtain a handle to it in your Activity, use the following snippet:

If you are sure that the size of the RecyclerView won't be changing, you can add the following to improve performance:

Step 2: Using a LayoutManager

Unlike a ListView, a RecyclerView needs a LayoutManager to manage the positioning of its items. You could define your own LayoutManager by extending the RecyclerView.LayoutManager class. However, in most cases, you could simply use one of the predefined LayoutManager subclasses:

  • LinearLayoutManager
  • GridLayoutManager
  • StaggeredGridLayoutManager

In this tutorial, I am going to use a LinearLayoutManager. This LayoutManager subclass will, by default, make your RecyclerView look like a ListView.

Step 3: Defining the Data

Just like a ListView, a RecyclerView needs an adapter to access its data. But before we create an adapter, let us create data that we can work with. Create a simple class to represent a person and then write a method to initialize a List of Person objects:

Step 4: Creating an Adapter

To create an adapter that a RecyclerView can use, you must extend RecyclerView.Adapter. This adapter follows the view holder design pattern, which means that it you to define a custom class that extends RecyclerView.ViewHolder. This pattern minimizes the number of calls to the costly findViewById method.

Earlier in this tutorial, we already defined the XML layout for a CardView that represents a person. We are going to reuse that layout now. Inside the constructor of our custom ViewHolder, initialize the views that belong to the items of our RecyclerView.

Next, add a constructor to the custom adapter so that it has a handle to the data that the RecyclerView displays. As our data is in the form of a List of Person objects, use the following code:

RecyclerView.Adapter has three abstract methods that we must override. Let us start with the getItemCount method. This should return the number of items present in the data. As our data is in the form of a List, we only need to call the size method on the List object:

Next, override the onCreateViewHolder method. As its name suggests, this method is called when the custom ViewHolder needs to be initialized. We specify the layout that each item of the RecyclerView should use. This is done by inflating the layout using LayoutInflater, passing the output to the constructor of the custom ViewHolder.

Override the onBindViewHolder to specify the contents of each item of the RecyclerView. This method is very similar to the getView method of a ListView's adapter. In our example, here's where you have to set the values of the name, age, and photo fields of the CardView.

Finally, you need to override the onAttachedToRecyclerView method. For now, we can simply use the superclass's implementation of this method as shown below.

Step 5: Using the Adapter

Now that the adapter is ready, add the following code to your Activity to initialize and use the adapter by calling the adapter's constructor and the RecyclerView's setAdapter method:

Step 6: Compile and Run

When you run the RecyclerView example on an Android device, you should see something similar to the following result.

Conclusion

In this tutorial, you have learned how to use the CardView and RecyclerView widgets that were introduced in Android Lollipop. You have also seen examples of how to make use of these widgets in Material Design apps. Note that even though a RecyclerView can do almost everything a ListView can, for small datasets, using a ListView is still preferable as it requires fewer lines of code.

You can refer to the Android Developers Reference for more information about the CardView and RecyclerView classes.


2015-03-23T16:55:09.000Z2015-03-23T16:55:09.000ZAshraff Hathibelagal

Getting Started With RecyclerView and CardView on Android

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

If you are interested in building an Android app that makes use of lists to display data, Android Lollipop features two new widgets to make your life easier, RecyclerView and CardView. Using these widgets, it is very easy to give your app a look and feel that conforms to the guidelines mentioned in Google's material design specification.

Prerequisites

To follow along, you should be using the latest version of Android Studio. You can get it from the Android Developer website.

1. Support Older Versions

At the time of writing, less than 2% of Android devices run Android Lollipop. However, thanks to the v7 Support Library, you can use the RecyclerView and CardView widgets on devices that run older versions of Android by adding the following lines to the dependencies section in your project's build.grade file:

2. Creating a CardView

A CardView is a ViewGroup. Like any other ViewGroup, it can be added to your Activity or Fragment using a layout XML file.

To create an empty CardView, you would have to add the following code to your layout XML as shown in the following snippet:

As a more realistic example, let us now create a LinearLayout and place a CardView inside it. The CardView could represent, for example, a person and contain the following:

  • TextView to display the name of the person
  • TextView to display the person's age
  • an ImageView to display the person's photo

This is what the XML would look like:

If this XML is used as the layout of an Activity, with the TextView and ImageView fields are set to meaningful values, then this is how it would render on an Android device:

A Stand-alone Card

3. Creating a RecyclerView

Step 1: Defining It in a Layout

Using a RecyclerView instance is slightly more complicated. However, defining it in a layout XML file is quite simple. You can define it in a layout as follows:

To obtain a handle to it in your Activity, use the following snippet:

If you are sure that the size of the RecyclerView won't be changing, you can add the following to improve performance:

Step 2: Using a LayoutManager

Unlike a ListView, a RecyclerView needs a LayoutManager to manage the positioning of its items. You could define your own LayoutManager by extending the RecyclerView.LayoutManager class. However, in most cases, you could simply use one of the predefined LayoutManager subclasses:

  • LinearLayoutManager
  • GridLayoutManager
  • StaggeredGridLayoutManager

In this tutorial, I am going to use a LinearLayoutManager. This LayoutManager subclass will, by default, make your RecyclerView look like a ListView.

Step 3: Defining the Data

Just like a ListView, a RecyclerView needs an adapter to access its data. But before we create an adapter, let us create data that we can work with. Create a simple class to represent a person and then write a method to initialize a List of Person objects:

Step 4: Creating an Adapter

To create an adapter that a RecyclerView can use, you must extend RecyclerView.Adapter. This adapter follows the view holder design pattern, which means that it you to define a custom class that extends RecyclerView.ViewHolder. This pattern minimizes the number of calls to the costly findViewById method.

Earlier in this tutorial, we already defined the XML layout for a CardView that represents a person. We are going to reuse that layout now. Inside the constructor of our custom ViewHolder, initialize the views that belong to the items of our RecyclerView.

Next, add a constructor to the custom adapter so that it has a handle to the data that the RecyclerView displays. As our data is in the form of a List of Person objects, use the following code:

RecyclerView.Adapter has three abstract methods that we must override. Let us start with the getItemCount method. This should return the number of items present in the data. As our data is in the form of a List, we only need to call the size method on the List object:

Next, override the onCreateViewHolder method. As its name suggests, this method is called when the custom ViewHolder needs to be initialized. We specify the layout that each item of the RecyclerView should use. This is done by inflating the layout using LayoutInflater, passing the output to the constructor of the custom ViewHolder.

Override the onBindViewHolder to specify the contents of each item of the RecyclerView. This method is very similar to the getView method of a ListView's adapter. In our example, here's where you have to set the values of the name, age, and photo fields of the CardView.

Finally, you need to override the onAttachedToRecyclerView method. For now, we can simply use the superclass's implementation of this method as shown below.

Step 5: Using the Adapter

Now that the adapter is ready, add the following code to your Activity to initialize and use the adapter by calling the adapter's constructor and the RecyclerView's setAdapter method:

Step 6: Compile and Run

When you run the RecyclerView example on an Android device, you should see something similar to the following result.

Conclusion

In this tutorial, you have learned how to use the CardView and RecyclerView widgets that were introduced in Android Lollipop. You have also seen examples of how to make use of these widgets in Material Design apps. Note that even though a RecyclerView can do almost everything a ListView can, for small datasets, using a ListView is still preferable as it requires fewer lines of code.

You can refer to the Android Developers Reference for more information about the CardView and RecyclerView classes.


2015-03-23T16:55:09.000Z2015-03-23T16:55:09.000ZAshraff Hathibelagal

Create Space Invaders with Swift and Sprite Kit: Introducing Sprite Kit

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

In this series, I will be teaching you how to create a Space Invaders inspired game using Sprite Kit and the Swift programming language. Along the way, you will learn about Sprite Kit's integrated physics engine, generate particles using Sprite Kit's built-in particle editor, use the accelerometer to move the player, and much more. Let's get started.

Introducing Sprite Kit

Sprite Kit is Apple's 2D game engine that was introduced along with iOS 7. With the introduction of the Swift programming language in 2014, there has never been a better time to be a game developer for iOS.

Sprite Kit provides a rendering engine built on top of OpenGL. With the use of textured sprites, a built-in physics engine, and the very powerful SKAction class, you can very quickly build functional 2D games.

Rendering Loop

Sprite Kit, like most game engines, utilizes a rendering loop to render and update the screen.The rendering loop has several steps it goes through before rendering the current scene. They are as follows:

  1. Update
  2. Evaluate actions
  3. Simulate physics
  4. Apply constraints
  5. Render the scene

Each of these has a corresponding method you can use to apply any additional logic that needs to take place at that time within the frame. Specifically, you would use the following methods within the scene.

  1. update
  2. didEvaluateActions
  3. didSimulatePhysics
  4. didApplyConstraints
  5. didFinishUpdate

 We are interested in two of these methods for this tutorial, update and didSimulatePhysics. We will use the update method to move the invaders manually and the didSimulatePhysics method to update the player, which will be controlled using the accelerometer and the physics engine.

SKNode

One of the building blocks of the Sprite Kit framework is the SKNode class. The SKNode class does not draw any visual assets. Its primary role is to provide baseline behavior that other classes implement. The SKScene class is the root node in a tree of SKNode instances and is used to hold sprites and other content that needs to be rendered.

The rendering and animation is done by an SKView instance that is placed inside a window and other views are then added to it. The SKScene instance is added to the SKView instance. You can use a single SKView instance in your window and switch between different scenes at any time.

The framework defines a number of SKNode subclasses. The most common one to build a scene is the SKSpriteNode class. The SKSpriteNode class can be drawn either as a rectangle with a SKTexture mapped onto it or as a colored, untextured rectangle. You'll most often use textured sprites, because this is how you will bring your artwork to life in your game. Check out the inheritance tree of the SKNode class to see what other types of nodes are available.

SKAction

The SKAction class is what brings your SKNode classes to life. By using the SKAction class you can move, rotate, scale, and fade the nodes. You can also use SKAction to play a sound and run custom code. The SKAction class is very powerful and, along with the SKNode class, is one of the building blocks of a Sprite Kit game.

Physics Engine

Sprite Kit has an integrated physics engine that makes handling complex physics situations a breeze. If you've ever tried to implement a physics engine on your own, you will appreciate this feature.

In Sprite Kit, the coordinate (0,0) is located at the bottom left of the screen instead of the top left, which you may be used to if you've worked with Flash, Corona, HTML5 Canvas, and many other game frameworks. This is because Sprite Kit uses OpenGL under the hood.

I highly suggest you read Apple's Sprite Kit Programming Guide to get more familiar with the above concepts. With this short introduction out of the way, let's get started building a game with Sprite Kit.

1. Project Setup

Open up Xcode and choose Create a new Xcode project or choose New > Project... from the File menu.

Create New Project

Make sure that you are targeting iOS,that the type is Application, and that you have chosen Game as the template type. Click Next to continue.

Choose Project Template

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. Specify a location to save the project files and click Create.

Choose Project Options

If you click the run button in the top left (or press Command-R), Xcode will build and run your application, displaying the text "Hello, World!". When you tap the screen, an image of a spaceship is added and starts rotating.

Default Game Screen Shot

2. Project Configuration

Select the project in the Project Navigator and open the General tab at the top. Under Deployment Info, uncheck all checkboxes but Portrait for Device Orientation.

Next, select and delete GameScene.sks. The .sks file allows you to lay out the scene visually. For this project, we will be adding every node programmatically. 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 its view property to an SKView instance and configure it.

You may have noticed the text in the lower right corner of the screen when you ran the application for the first time. 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.

If some of the nodes were to move off-screen, the node count would drop, but they would still be in memory. This is important to remember and don't let the node count fool you. If you add 100 nodes to a scene and 90 of them are off-screen, you still have 100 nodes taking up memory.

For optimization purposes, the ignoresSiblingOrder is set to true. You can read more about this in Sprite Kit Programming Guide. The last thing we do is invoke the SKView's presentScene method and pass in the StartGameScene, which we will create in the next step.

Lastly, we don't want the status bar to be shown so we return true from the preferStatusBarHidden method.

3. Creating StartGameScene

Step 1: Adding the StartGameScene Class

Choose New> File... from the File menu and choose Cocoa Touch Class from the iOS > Source section. Click Next to continue.

Create new Class

Next, name the class StartGameScene and make sure it inherits from SKScene. Language should be set to Swift. Click Next to continue.

Tell Xcode where you'd like to save the file for the new class and click Create. Add the following code to StartGameScene.swift.

The didMoveToView(_:) 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 the game now you should be presented with a black screen that shows the frame rate and node count in the lower right corner of the screen.

Step 2: Adding startGameButton

It's no fun looking at a black screen so let's create our first SKSpriteNode instance. Update the didMoveToView(_:) method as shown below.

We declare a constant startGameButton using the convenience initializer init(imageNamed:), which takes as argument the name of the image. We center it on the screen both horizontally and vertically, except we subtract 100 points to place it a little off-center on the vertical axis. We set its name property to startgame so we can refer back to it later. Lastly, we add it to the scene by invoking addChild(_:), which takes as argument the node to add to the scene. You can learn more about the SKSpriteNode class in the SpriteKit Framework Reference.

Now would be a good time to add the images to the project. Download the source files of this tutorial and find the folder named images. Drag it onto the folder that has the name of whatever you named your project, for example, MobileTutsInvaderz. Make sure Copy items if needed is checked as well as the main target in the list of targets.

Adding Images Folder

If you test your application, you should see a button labeled "New Game".

New Game Button

Step 3: Implementing touchesBegan

Next, we need to implement the touchesBegan(_:withEvent:) method. Its implementation is shown below. The touchesBegan method is invoked when one or more fingers touch down on the screen.

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 calling AnyObject on the touches set since there is only one object in the set.

We store the location of the touch in the scene in a constant named touchLocation. We do this by invoking locationInNode(_:) on the touch object, passing in the scene. We can then figure out which node was touched by invoking nodeAtPoint, passing in the touch location. With this node touchedNode found, we can check the name property and, if it is equal to startgame, we know they tapped the button.

If the user tapped the button, we instantiate the GameScene class and set its scaleMode to be the same as the current scene's scale mode. We then create a SKTransition named transitionType and show the scene by invoking presentScene(_:transition:) passing in the gameOverScene and the transitionType.

There are quite a few SKTransistion types to choose from. You can read more about them in the SpriteKit Framework Reference. I suggest you try out a few and see which ones you like best.

If you test your application, you can tap the button, which takes you to the GameScene. This is the same scene the project initially started out with.

Conclusion

This bring the first part of this series to a close. You have been introduced to Sprite Kit and have learned how to create custom scenes, use the SKSpriteNode class, and detect touches. This is only the beginning, we still have a lot to learn. Thanks for reading and I'll see you in the next part of this series.

2015-03-25T16:45:36.000Z2015-03-25T16:45:36.000ZJames Tyner

Windows Phone 8 Succinctly: Integrating With the Hardware

$
0
0

In this article, we're going to explore how you can make use of the hardware capabilities of a Windows Phone device, such as geolocation, device sensors, Bluetooth, and NFC.

Geolocation

All Windows Phone devices have built-in geolocation hardware. By using a combination of 3G, Wi-Fi, and GPS signal, the phone is able to identify the user’s location and make it available to every app, thanks to a set of APIs included in the Windows Runtime.

Geolocation is another scenario where APIs are duplicated. The original API set was part of the Silverlight framework, but it has been expanded in the Windows Runtime.

The new main class for working with geolocation services is called Geolocator, and it’s part of the Windows.Devices.Geolocation namespace.

Note: To use geolocation services, you’ll need to enable the ID_CAP_LOCATION capability in the manifest file.

The first step to use geolocation services is to check the LocationStatus property value of the Geolocator class to identify the current status of the services. Specifically, we have to manage the PositionStatus.Disabled status. In this case, the user has disabled the geolocation services in the phone’s settings, so we don’t have to execute any operation related to geolocation, otherwise we will get an exception. 

If you want to keep track of the geolocation service’s status, there’s a specific event handler called StatusChanged that is invoked every time the status changes. It helps you to identify, for example, that the GPS is ready or that the user is in a location that is hard to track.

There are two ways to interact with the Geolocator class: asking for a single position (for example, a Twitter client that needs to geolocalize a tweet), or subscribing to an event handler that can be used to continuously track the user’s location (for example, a running tracker app).

To ask for a single position, you simply have to call the asynchronous method GetGeopositionAsync(). It will return a Geoposition object containing a Coordinate property that will help you to identify where the user is.

Note: The Geoposition object has another property called CivicAddress which should contain a reference to the user’s location using civic references (like the city, street address, etc.). This property isn’t supported, so it will always return incorrect information. Later in this article we’ll look at how to get the civic position of the user.

The following code sample demonstrates how to get a single user’s position:

To continuously track the user’s position, instead, you need to subscribe to the PositionChanged event handler, which is invoked every time the user moves from the previous location. You can control how often this event is raised by setting three properties of the Geolocator object:

  • DesiredAccuracy, which is the geolocation accuracy. The higher it is set, the more precise the result will be, and the more battery power will be consumed.
  • MovementThreshold, which is the distance, in meters, the user should move from the previous location before the PositionChanged event is triggered.
  • ReportInterval, which is the minimum number of milliseconds that should pass between two detections.

The PositionChanged event returns a parameter that contains a Position property of type Geoposition—it works the same way as we’ve previously seen for the GetGeopositionAsync() method.

In the previous sample, we track the user’s location every time he or she moves 100 meters from the previous location, only if at least one second has passed since the previous detection. Every time the PositionChanged event is raised, we display the Latitude and Longitude properties’ values in two different TextBlock controls. Note that we’re using the Dispatcher class we discussed earlier in this series. It’s required because the PositionChanged event is managed in a background thread, so we are not able to directly interact with the UI.

Tip: You can easily test geolocation services by using the tool that comes with the emulator. Simply click a position on the map and the related coordinates will be sent to the emulator.

Background Tracking

Windows Phone 8 has introduced the ability to keep tracking the user’s position when the application is suspended. This means that the PositionChanged event handler will continue to be invoked even if the app is not running in the foreground.

Background tracking can continue unless:

  • the application stops tracking the user’s location by deregistering the PositionChanged and StatusChanged event handlers
  • the application has been running in the background for four hours without being reopened
  • Battery Saver mode is enabled
  • the phone is running out of free memory
  • geolocation services have been disabled
  • the user opens another application that is able to track his or her location in the background

To activate background tracking, you need to edit the manifest file using the manual editor (right-click the file and choose View code) since the option is not supported by the visual editor. You’ll have to edit the DefaultTask node in the following way:

Now, if the previous conditions are satisfied, the application will keep tracking the user’s location even when it’s not running in the foreground.

If you want to customize the user experience based on whether the application is running in the background, you can subscribe to a specific event of the PhoneApplicationService object, which is declared in the App.xaml file, and which we learned to use earlier in this series. The event handler is called RunningInBackground and it’s triggered every time the application is suspended. However, since it’s using geolocation services, it will keep running in the background.

In the following sample, you can see how the PhoneApplicationService declaration will look after we’ve subscribed to the event:

In the previous sample, we set a property (called IsRunningInBackground) to know whether the app is running in the background. We set it to true when the RunningInBackground event is triggered, and set it to false when the Activated event is raised, which means that the application has been reopened.

Interacting With the Map Control

Windows Phone includes a built-in Map control that can be used to embed a map inside an application’s page and can be used in combination with the geolocation services. The control has been greatly improved since Windows Phone 7, and it’s now based on Nokia’s cartography. In addition, it supports offline maps—if the user has downloaded maps for the current location, the control will be able to automatically use them. The Map control is part of the Microsoft.Phone.Maps.Controls namespace, so you’ll need to add it to your XAML page before using it:

The Map control exposes many properties for customization. The most useful ones are:

  • Center, the geolocation coordinates the map is centered at.
  • ZoomLevel, which is the zoom level from 1 (minimum) to 19 (maximum).
  • CartographicMode, which can be used to switch between Aerial (satellite view), Road (road view), Terrain (landscape view), and Hybrid (a combination of the others).
  • ColorMode can be used to set a Light or Dark theme, according to the luminosity conditions.

In the following sample, you can see a Map control included in a page:

The Map Control

Using the Map control in combination with the geolocation services should be easy: it would be enough to set the Center property of the Map with a Geoposition object returned by the Geolocator class. Unfortunately, there’s a limitation since Windows Phone and the Map control use two different classes to store geolocation coordinates. The first one is called Geocoordinate and it’s part of the Windows.Devices.Geolocation namespace, while the second one is called GeoCoordinate (with a capital C) and it’s part of the System.Device.Location namespace.

Fortunately, there’s a work-around: installing the Windows Phone Toolkit we discussed earlier in this series. In addition to providing a useful set of additional controls, it also offers many helpers and extensions that are useful when working with the Map control.

Specifically, after adding the Windows Phone Toolkit to your project (the easiest way is using NuGet), you will be able to use an extension method called ToGeoCoordinate(), which is able to convert the original Windows Runtime class to the Map control’s specific one. In the following sample, you can see how we use it to display the user’s current location on a map:

Layers

The Map control supports layers that can be added on top of the map. A layer is a collection of visual objects that are displayed over the map, and it’s represented by the MapLayer class.

Each MapLayer has a collection of overlays (the MapOverlay class); each one is an object that is displayed on the map.

An overlay can be composed of virtually any control. In fact, it’s defined by a position using the GeoCoordinate property, and content using the Content property, which is a generic object. This means that you can add any object you want as content, as with any of the XAML visual controls available in the framework.

In the following sample, we create a Rectangle object and set it as Content of a MapOverlay object that we add to a new layer.

A Layer Displayed over a Map Control

Routing

A common scenario in which you work with the Map control is with routing, where you have the ability to show routes on the map. Even if it sounds complicated, it’s easy to implement using the RouteQuery class, which allows you to:

  • set different route options by using the TravelMode and RouteOptimization properties
  • add a list of waypoints that compose the route

The following code demonstrates a routing sample:

The TravelMode and RouteOptimization options can be used to customize the route in a way similar to what many GPS navigators do. In the previous sample, we want the driving route that requires the least amount of time.

The path is set using the Waypoints property, which requires a collection of GeoCoordinate objects. Each object represents a point in the path that should be touched by the route.

The RouteQuery class works using the callback approach. We call the QueryAsync() method and subscribe to the QueryCompleted event, which is triggered when the route has been calculated, as shown in the following sample:

Displaying a route on the Map control is easy—you simply have to create a new MapRoute object, passing the query result (stored in the Result property of the returned object) as a parameter, and add it to the Map using the AddRoute() method.

A Route Displayed on a Map

Working With Coordinates

Until now, we’ve always worked with geolocation coordinates based on latitude and longitude, but often it’s easier for users to understand a location based on its civic address. Windows Phone 8 has introduced two classes to perform geocoding conversion: GeoCodeQuery (to convert an address into a set of numeric coordinates) and ReverseGeocodeQuery (to convert latitude and longitude into an address).

They both work in the same way, since they use the same callback approach we’ve seen for routing. After you’ve defined the operation to perform, you can start the search using the QueryAsync() method. Once the search has completed, you can use the QueryCompleted event handler to manage the results.

The GeocodeQuery class requires you to set two parameters: GeoCoordinate and, most important, SearchTerm, which is the search keyword. GeoCoordinate shouldn’t be required (since the purpose of this class is to find the location’s coordinate), but you’ll have to set it anyway with a fake value as shown in the following sample. Otherwise, you won’t get any result.

The ReverseGeoCodeQuery class, instead, only requires the GeoCoordinate property to be set with the location’s coordinates.

The QueryCompleted event handler is the same for both classes and returns a collection of MapLocation objects. If you used the GeocodeQuery class, you’ll probably be interested in the GeoCoordinate object, which contains the latitude and longitude of the searched location.

The previous sample shows a way to center the map on the position returned by the service.

Instead, if you used the ReverseGeocodeQuery class, you’ll find the information you’re looking for in the Information property that contains data like City, Street, Address, etc.

In both cases, the event handler returns a collection of MapLocation objects because, especially if you searched a location by a keyword, the service can return multiple results. The previous example shows the information about the first item in the collection.

How to Publish an Application That Uses the Map Control

You can freely use the Map control during the testing phase, but when you submit it to the Store, you’ll need production credentials.

The credentials can be obtained during the submission process. One of the optional steps is called Map service, which will give you two codes called ApplicationId and AuthenticationToken. Once you have the codes, you need to set them in the following way when the application starts:

Movement Sensors

Windows Phone devices have many movement sensors that can be used by applications, like the accelerometer, gyroscope, and compass. The Windows Runtime has introduced a new set of APIs which are part of the Windows.Devices.Sensors namespace:

  • The Accelerometer class can be used to interact with the accelerometer.
  • The Gyrometer class can be used to interact with the gyroscope.
  • The Compass class can be used to interact with the compass.
  • OrientationSensor is a special class that can combine values obtained from all the available sensors.

Note: To use sensors, you’ll need to enable the ID_CAP_SENSORS option in the manifest file. If you also want to use gyroscope and compass, you need to enable the ID_REQ_MAGNETOMETER and ID_REQ_GYROSCOPE capabilities in the Requirements section of the manifest file. This way, users with devices without one of these sensors won’t be able to download your application.

All the sensors work in the same way. You’ll be able to get a reference to the sensor using the GetDefault() method. If it’s not available on the phone (for example, not all devices have a gyroscope), you’ll get a null reference in return. It’s important to always check if the returned sensor is null before doing any operation.

Like the geolocation services, you have two ways to interact with sensors:

  • the GetCurrentReading() method, which returns a single detection
  • the ReadingChanged event handler, which is triggered every time the phone moves to a new position

In this section, we’ll use as an example the OrientationSensor class, which is a special sensor that is able to combine all the values returned by the available sensors and automatically filter all the out-of-scale data. The class returns an OrientationSensorReading object, which contains all the information about the current position. You’ll be able to get the device position by using the Quaternion and RotationMatrix properties. 

In the following samples, you can see two ways to achieve the same result: getting a single reading, and subscribing to notifications that are sent every time the position changes. The device’s coordinates on the x-axis, y-axis, and z-axis are displayed on the screen using three TextBlock controls:

Please note that if you decide to subscribe to the ReadingChanged event, you’ll need a Dispatcher to communicate with the user interface since the event handler is managed by a background thread.

If you need to use a specific sensor, the code to use is very similar. You’ll simply have to use the specific sensor class and manage the specific reading object that you’ll get in return.

Tip: The Windows Phone emulator features a tool to simulate movement sensors. Unfortunately, only the accelerometer is supported; for every other sensor, including the OrientationSensor, you’ll need a real device.

Determining the Current Hardware

Windows Phone offers a class called DeviceStatus that can be used to get information about the current device, like:

  • the firmware version, with the DeviceFirmwareVersion property
  • the hardware version, with the DeviceHardwareVersion property
  • the manufacturer, with the DeviceManufacturer property
  • the device name, with the DeviceName property
  • the amount of total memory available, with the DeviceTotalMemory property

Plus, you have access to some useful APIs to get the current status of the battery. They belong to the Windows.Phone.Devices.Power namespace, and you’ll be able to use the Battery class to identify the percentage of remaining battery charge (with the RemainingChargePercent property) and the remaining time before the battery totally discharges (with the RemainingDischargeTime property).

The Battery class behaves like a sensor; you’ll have to use the GetDefault() method to get a reference to it (even if, in this case, you can avoid checking whether the returned object is null since every phone has a battery), as in the following sample:

In addition, the DeviceStatus class offers a property called PowerSource, which tells you the current power source, and an event handler, called PowerSourceChanged, which is triggered every time the current power source changes (from battery to external or vice versa).

It can be useful if, for example, you want to avoid performing power-consuming operations if the phone is not connected to an external power source.

Note: To get access to hardware info, you’ll need to enable the ID_CAP_IDENTITY_DEVICE capability in the manifest file.

Proximity

Under the proximity category we can include all the new APIs that have been introduced in the Windows Runtime to connect two devices together without using an Internet connection. In Windows Phone you can achieve this result by using two technologies: Bluetooth and NFC.

Bluetooth is well known and can be used to connect devices within a range of 10 meters. It’s been available since the first Windows Phone release, but only Windows Phone 8 has introduced APIs that are available to developers.

NFC is a more recent technology that has started to gain some traction in recent years. It can be used to exchange small amounts of data within a close range (the two devices should basically touch each other). NFC is an interesting technology since it works not only with active devices (like two phones), but also with passive devices (like chips embedded in a sticker or in a magazine page). In addition, Windows Phone is able to extend NFC and use it also to create a Bluetooth communication channel without needing to manually pair the two devices. This way, you can overcome NFC’s limitations and use Bluetooth to transfer larger data files, like images.

Note: To use Proximity APIs, you’ll need to enable the ID_CAP_PROXIMITY option in the manifest file.

The easiest way to test applications that use the Proximity APIs is with real devices, but there’s also a third-party tool called Proximity Tapper available on CodePlex that can be used to simulate the connection between different emulators (since Visual Studio is able to run only one specific emulator at a time, you’ll have to use different emulator versions, for example a WVGA and a WXGA one).

Exchanging Messages

A common scenario when working with NFC is the exchange of messages, which represents a small amount of data. There are some standard messages that Windows Phone is able to manage automatically (for example, when you receive a URI or a contact), and some custom messages which can be managed only by third-party apps.

The first step, as with every other sensor we’ve seen so far, is to use the GetDefault() method of the ProximityDevice class to get access to the proximity sensor. In this case, we also need to check if the sensor reference is null before moving on, since some devices don’t support NFC.

Every message is identified by a specific keyword. The Windows Phone APIs natively support three message types—text, URI, and binary. Let’s see how to manage them.

Text Messages

Publishing a text message is easy. We use the PublishMessage() method of the ProximityDevice class, which requires the message type and the content as parameters. In the following sample, you can see how we send a text message, identified by the Windows.SampleMessage keyword.

As you can see, the PublishMessage() method accepts a third, optional parameter, which is an event that is raised when the message has been received by the other device. This event can be useful, as shown in the previous sample, to stop sending the message once it has been received by calling the StopPublishingMessage() method on the ProximityDevice object. You need to set the message ID, which is passed as a parameter of the method.

The phone receiving the message should instead call the SubscribeForMessage() method. Unlike the publishing method, this method is the same regardless of the data we expect. The difference is that, according to the message, we can use some specific properties to parse it and extract the information we need.

In the following sample you can see how it’s easy to extract the message content thanks to the DataAsString property of the ProximityMessage class:

This code is not very different from the code used to send the message; the SubscribeForMessage() method requires the message type and the event handler that is invoked when the message has been received.

The message is received thanks to the ProximityMessage object that is returned as a parameter. In this case, since it’s a text message, we can extract the content using the DataAsString property. Note that again in this situation we cancel the subscription by using the StopSubscribingForMessage() method so that the application won’t listen anymore for the incoming message.

URI

Sending URIs works in a similar way, except that we need to use the PublishUriMessage() method that accepts the Uri to send as a parameter. In this case, we don’t need to set the message type since it’s implicit.

The difference is that Uri messages are directly supported by Windows Phone, so you’ll be able to exchange them without using a receiver application. The operating system, once it has received the Uri, will simply ask the user if he or she wants to open the browser to see it.

However, if you still want to manage Uris in your application, you can subscribe to receive them. In this case, you’ll have to listen for the incoming WindowsUri message. In addition, you’ll need some more code to extract it since it’s not treated as a string; you’ll need to work directly with a byte array, as in the following sample:

NDEF Messages

NDEF (NFC Data Exchange Format) is a standard protocol used to define NFC messages that can be used to exchange different data types across different platforms. Some common scenarios are exchanging geolocation data, mail sending, and social network sharing.

NDEF isn’t natively supported by Windows Phone APIs. To avoid requiring developers to manually create the binary data needed to compose a message, a developer named Andreas Jakl has created a library called NDEF Library For Proximity API, which is available on CodePlex and can be easily installed using NuGet.

This library features many classes that encapsulate the needed logic for the most common messages, like NdefGeoRecord for sharing geolocation coordinates, NdefLaunchAppRecord to open another Windows Phone application, and NdefTelRecord to start a phone call to a specific number. You can see a complete list of the supported records on the official website.

In the following sample, you’ll see how to send a message that contains an NdefSmsRecord which can be used to create a new SMS message with predefined text:

The first step is to create the record and set the needed properties. In this sample, we need to set the SmsNumber (the phone number that will receive the message) and SmsBody (the message’s text) properties.

Next, we need to encapsulate the record into a new message, which is identified by the NdefMessage class. In the end, we can send it; in this scenario we need to use the PublishBinaryMessage() method of the ProximityDevice class, since it’s not a standard message but a binary one. As you can see, we pass as parameter (other than the message’s type, which is NDEF) the message as a bytes array.

If the message’s type is natively supported by Windows Phone, the device will automatically manage the incoming message. With the previous sample, the operating system will prompt to the user to send a SMS message. Instead, if we want to receive it within an application, we’ll need to do some additional work. Since it’s a binary message, we’ll need to extract the needed information. Fortunately, the NDEF Library for Proximity API will help us, as you can see in the following sample:

We need to subscribe for incoming NDEF messages. When we receive the message, we are able to convert the binary data (which is available in the Data property of the ProximityMessage class) into a NdefMessage again, thanks to the FromByteArray() method.

An NdefMessage object can contain more than one record, so we need to iterate it and extract every NdefRecord object that is stored. In the previous sample, since we expect to only get an NdefSmsRecord, we manage only this scenario. The task is accomplished by using the CheckSpecializedType() method on the record, which returns its data type. We manage it only if it’s the type we’re expecting. We are able to get the original record simply by creating a new NdefSmsRecord object and passing, as a parameter, the NdefRecord object stored in the message.

Once we have it, we are able to access all its properties. In the previous sample, we show the user the body of the SMS message.

Writing Messages to a Tag

As mentioned previously, NFC can be used with passive devices, like tags and stickers. Windows Phone devices are able to write data to NFC tags simply by adding the :WriteTag suffix to the message’s type when publishing a message.

In the following code you can see how to adapt the previous sample to write the record into a tag instead of sending it to another device:

Creating a Communication Channel Using NFC

As previously mentioned, NFC can be used only to exchange small amounts of data—it can’t be used to maintain a stable communication channel. The best technology to achieve this result is Bluetooth. However, we’re able to use NFC as a shortcut to establish a Bluetooth channel between two devices that have the same installed application.

Note: In this case we also need to enable the ID_CAP_NETWORKING option in the manifest file.

The starting point is the PeerFinder class, which can be used (on both devices) to start the connection and look for another device to pair with. Using it is quite simple: you have to subscribe to the TriggeredConnectionStateChanged event that is triggered when the connection status changes, and start the pairing process by calling the Start() method.

You’ll need to use the same code on both devices. However, there’s a work-around to automatically execute it in case the app is opened by a pairing request. In fact, when you execute the previous code and connect the two devices together, Windows Phone will automatically intercept the incoming message and will prompt the user to open the required application. When this happens, the application is opened with the following special URI:

By using the OnNavigatedTo event on the main page we are able to intercept this special URI and automatically start the pairing process, as shown in the following sample:

The TriggeredConnectionStateChanged event can be used to manage the actual connection status. The most important state is Completed, which is triggered when the connection has been successfully established and you can start to exchange data.

In the following sample, you can see that once the connection is established, we store the channel (identified by a StreamSocket object) in another variable to be used later for further communications.

Other than saving a reference to the channel, we start listening for incoming messages (we’ll see how in a moment) and we call the Stop() method of the PeerFinder class. Since the channel has been created, we can stop the pairing process.

Listening for Incoming Messages

The listening process works in a way similar to polling; until the channel is opened, we keep asking the other device if there’s a new message. In the following sample, we exchange text messages by using the DataReader and DataWriter classes we learned to use earlier in this series in the context of storing data in the local storage.

While the channel is opened and the listening process is active, we keep calling the GetMessage() method. If there’s an incoming message in the channel, we display it to the user. The polling procedure is implemented using a while loop, which is repeated until the isListening variable is set to true.

The GetMessage() method is simply a helper that, by using the DataReader class, is able to get the channel’s data (which is stored as binary in the InputStream property of the StreamSocket class) and convert it into a plain string.

Sending a Message

To send a message, we need to use the DataWriter class to write the data in the OutputStream channel of the StreamSocket object. We have to send two pieces of information: the message size by using the WriteInt32() method, and the message text by using the WriteString() message.

If you want to send a message on the channel, it’s enough to use the SendMessage() method we’ve just defined:

Creating a Communication Channel Using Bluetooth

The approach to creating a communication channel using Bluetooth is the same we’ve previously seen. A channel is identified by the StreamSocket class, and we can send and listen for incoming messages exactly in the same way.

What changes is the way we connect to another device. With NFC, the peer-to-peer communication is necessarily made between the two devices that are connected. With Bluetooth, instead, you can virtually connect to any device within your phone’s range. 

We’re going to use the PeerFinder class again, but this time, instead of starting the pairing process using the Start() method, we look for all the available peers with the FindAllPeersAsync() method. It returns a collection of PeerInformation objects—each one is a device that can connect with our application.

In the following sample, we simply display the list of available devices to the user, by setting the collection as ItemsSource of a ListBox control:

Notice that we’ve embedded our code into a try/catch statement; in fact, the user may have Bluetooth turned off. While we start looking for other peers, if we get an exception with the error code 0x8008048F, it means that we are in this situation, so we have to properly manage it (for example, by informing the user that he or she needs to turn it on to use the application).

After the user has chosen which device he or she wants to connect with, we need to call the ConnectAsync() method of the PeerFinder class, passing the PeerInformation object that represents the device as a parameter. Next, exactly like we did for the NFC communication, we start listening for messages and stop looking for other peers using the Stop() method, as shown in the following sample:

The StartListeningForMessage() method is the same method we used to deal with NFC communication.

On the other side (the phone that the user has selected to interact with), if we want to accept the incoming communication request from another phone, we need to again use the Start() method of the PeerFinder class and subscribe to the ConnectionRequested event, which is triggered when another device has requested to establish a connection.

In the event handler we simply have to call the ConnectAsync() method of the PeerFinder class like we did with the phone that started the connection request. We’ll get a reference to the device that sent the request in the method’s parameters.

Conclusion

In this article we’ve seen how to interact with the hardware features that every Windows Phone device has. Specifically:

  • We’ve seen how to interact with the geolocation services, retrieve the user’s location, and interact with the Map control.
  • We’ve learned how to use the motion sensors to determine the device’s position in space. It’s a feature particularly useful with games, since many of them are easier to control with the accelerometer rather than with virtual controls.
  • We’ve briefly covered the hardware APIs that are useful for obtaining information about the device on which the app is running.
  • We’ve discussed Proximity APIs, which have been introduced in the Windows Runtime to connect two devices without requiring an Internet connection. Specifically, we’ve talked about two technologies: NFC and Bluetooth.
2015-03-26T19:13:12.000Z2015-03-26T19:13:12.000ZMatteo Pagani

Windows Phone 8 Succinctly: Integrating With the Hardware

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

In this article, we're going to explore how you can make use of the hardware capabilities of a Windows Phone device, such as geolocation, device sensors, Bluetooth, and NFC.

Geolocation

All Windows Phone devices have built-in geolocation hardware. By using a combination of 3G, Wi-Fi, and GPS signal, the phone is able to identify the user’s location and make it available to every app, thanks to a set of APIs included in the Windows Runtime.

Geolocation is another scenario where APIs are duplicated. The original API set was part of the Silverlight framework, but it has been expanded in the Windows Runtime.

The new main class for working with geolocation services is called Geolocator, and it’s part of the Windows.Devices.Geolocation namespace.

Note: To use geolocation services, you’ll need to enable the ID_CAP_LOCATION capability in the manifest file.

The first step to use geolocation services is to check the LocationStatus property value of the Geolocator class to identify the current status of the services. Specifically, we have to manage the PositionStatus.Disabled status. In this case, the user has disabled the geolocation services in the phone’s settings, so we don’t have to execute any operation related to geolocation, otherwise we will get an exception. 

If you want to keep track of the geolocation service’s status, there’s a specific event handler called StatusChanged that is invoked every time the status changes. It helps you to identify, for example, that the GPS is ready or that the user is in a location that is hard to track.

There are two ways to interact with the Geolocator class: asking for a single position (for example, a Twitter client that needs to geolocalize a tweet), or subscribing to an event handler that can be used to continuously track the user’s location (for example, a running tracker app).

To ask for a single position, you simply have to call the asynchronous method GetGeopositionAsync(). It will return a Geoposition object containing a Coordinate property that will help you to identify where the user is.

Note: The Geoposition object has another property called CivicAddress which should contain a reference to the user’s location using civic references (like the city, street address, etc.). This property isn’t supported, so it will always return incorrect information. Later in this article we’ll look at how to get the civic position of the user.

The following code sample demonstrates how to get a single user’s position:

To continuously track the user’s position, instead, you need to subscribe to the PositionChanged event handler, which is invoked every time the user moves from the previous location. You can control how often this event is raised by setting three properties of the Geolocator object:

  • DesiredAccuracy, which is the geolocation accuracy. The higher it is set, the more precise the result will be, and the more battery power will be consumed.
  • MovementThreshold, which is the distance, in meters, the user should move from the previous location before the PositionChanged event is triggered.
  • ReportInterval, which is the minimum number of milliseconds that should pass between two detections.

The PositionChanged event returns a parameter that contains a Position property of type Geoposition—it works the same way as we’ve previously seen for the GetGeopositionAsync() method.

In the previous sample, we track the user’s location every time he or she moves 100 meters from the previous location, only if at least one second has passed since the previous detection. Every time the PositionChanged event is raised, we display the Latitude and Longitude properties’ values in two different TextBlock controls. Note that we’re using the Dispatcher class we discussed earlier in this series. It’s required because the PositionChanged event is managed in a background thread, so we are not able to directly interact with the UI.

Tip: You can easily test geolocation services by using the tool that comes with the emulator. Simply click a position on the map and the related coordinates will be sent to the emulator.

Background Tracking

Windows Phone 8 has introduced the ability to keep tracking the user’s position when the application is suspended. This means that the PositionChanged event handler will continue to be invoked even if the app is not running in the foreground.

Background tracking can continue unless:

  • the application stops tracking the user’s location by deregistering the PositionChanged and StatusChanged event handlers
  • the application has been running in the background for four hours without being reopened
  • Battery Saver mode is enabled
  • the phone is running out of free memory
  • geolocation services have been disabled
  • the user opens another application that is able to track his or her location in the background

To activate background tracking, you need to edit the manifest file using the manual editor (right-click the file and choose View code) since the option is not supported by the visual editor. You’ll have to edit the DefaultTask node in the following way:

Now, if the previous conditions are satisfied, the application will keep tracking the user’s location even when it’s not running in the foreground.

If you want to customize the user experience based on whether the application is running in the background, you can subscribe to a specific event of the PhoneApplicationService object, which is declared in the App.xaml file, and which we learned to use earlier in this series. The event handler is called RunningInBackground and it’s triggered every time the application is suspended. However, since it’s using geolocation services, it will keep running in the background.

In the following sample, you can see how the PhoneApplicationService declaration will look after we’ve subscribed to the event:

In the previous sample, we set a property (called IsRunningInBackground) to know whether the app is running in the background. We set it to true when the RunningInBackground event is triggered, and set it to false when the Activated event is raised, which means that the application has been reopened.

Interacting With the Map Control

Windows Phone includes a built-in Map control that can be used to embed a map inside an application’s page and can be used in combination with the geolocation services. The control has been greatly improved since Windows Phone 7, and it’s now based on Nokia’s cartography. In addition, it supports offline maps—if the user has downloaded maps for the current location, the control will be able to automatically use them. The Map control is part of the Microsoft.Phone.Maps.Controls namespace, so you’ll need to add it to your XAML page before using it:

The Map control exposes many properties for customization. The most useful ones are:

  • Center, the geolocation coordinates the map is centered at.
  • ZoomLevel, which is the zoom level from 1 (minimum) to 19 (maximum).
  • CartographicMode, which can be used to switch between Aerial (satellite view), Road (road view), Terrain (landscape view), and Hybrid (a combination of the others).
  • ColorMode can be used to set a Light or Dark theme, according to the luminosity conditions.

In the following sample, you can see a Map control included in a page:

The Map Control

Using the Map control in combination with the geolocation services should be easy: it would be enough to set the Center property of the Map with a Geoposition object returned by the Geolocator class. Unfortunately, there’s a limitation since Windows Phone and the Map control use two different classes to store geolocation coordinates. The first one is called Geocoordinate and it’s part of the Windows.Devices.Geolocation namespace, while the second one is called GeoCoordinate (with a capital C) and it’s part of the System.Device.Location namespace.

Fortunately, there’s a work-around: installing the Windows Phone Toolkit we discussed earlier in this series. In addition to providing a useful set of additional controls, it also offers many helpers and extensions that are useful when working with the Map control.

Specifically, after adding the Windows Phone Toolkit to your project (the easiest way is using NuGet), you will be able to use an extension method called ToGeoCoordinate(), which is able to convert the original Windows Runtime class to the Map control’s specific one. In the following sample, you can see how we use it to display the user’s current location on a map:

Layers

The Map control supports layers that can be added on top of the map. A layer is a collection of visual objects that are displayed over the map, and it’s represented by the MapLayer class.

Each MapLayer has a collection of overlays (the MapOverlay class); each one is an object that is displayed on the map.

An overlay can be composed of virtually any control. In fact, it’s defined by a position using the GeoCoordinate property, and content using the Content property, which is a generic object. This means that you can add any object you want as content, as with any of the XAML visual controls available in the framework.

In the following sample, we create a Rectangle object and set it as Content of a MapOverlay object that we add to a new layer.

A Layer Displayed over a Map Control

Routing

A common scenario in which you work with the Map control is with routing, where you have the ability to show routes on the map. Even if it sounds complicated, it’s easy to implement using the RouteQuery class, which allows you to:

  • set different route options by using the TravelMode and RouteOptimization properties
  • add a list of waypoints that compose the route

The following code demonstrates a routing sample:

The TravelMode and RouteOptimization options can be used to customize the route in a way similar to what many GPS navigators do. In the previous sample, we want the driving route that requires the least amount of time.

The path is set using the Waypoints property, which requires a collection of GeoCoordinate objects. Each object represents a point in the path that should be touched by the route.

The RouteQuery class works using the callback approach. We call the QueryAsync() method and subscribe to the QueryCompleted event, which is triggered when the route has been calculated, as shown in the following sample:

Displaying a route on the Map control is easy—you simply have to create a new MapRoute object, passing the query result (stored in the Result property of the returned object) as a parameter, and add it to the Map using the AddRoute() method.

A Route Displayed on a Map

Working With Coordinates

Until now, we’ve always worked with geolocation coordinates based on latitude and longitude, but often it’s easier for users to understand a location based on its civic address. Windows Phone 8 has introduced two classes to perform geocoding conversion: GeoCodeQuery (to convert an address into a set of numeric coordinates) and ReverseGeocodeQuery (to convert latitude and longitude into an address).

They both work in the same way, since they use the same callback approach we’ve seen for routing. After you’ve defined the operation to perform, you can start the search using the QueryAsync() method. Once the search has completed, you can use the QueryCompleted event handler to manage the results.

The GeocodeQuery class requires you to set two parameters: GeoCoordinate and, most important, SearchTerm, which is the search keyword. GeoCoordinate shouldn’t be required (since the purpose of this class is to find the location’s coordinate), but you’ll have to set it anyway with a fake value as shown in the following sample. Otherwise, you won’t get any result.

The ReverseGeoCodeQuery class, instead, only requires the GeoCoordinate property to be set with the location’s coordinates.

The QueryCompleted event handler is the same for both classes and returns a collection of MapLocation objects. If you used the GeocodeQuery class, you’ll probably be interested in the GeoCoordinate object, which contains the latitude and longitude of the searched location.

The previous sample shows a way to center the map on the position returned by the service.

Instead, if you used the ReverseGeocodeQuery class, you’ll find the information you’re looking for in the Information property that contains data like City, Street, Address, etc.

In both cases, the event handler returns a collection of MapLocation objects because, especially if you searched a location by a keyword, the service can return multiple results. The previous example shows the information about the first item in the collection.

How to Publish an Application That Uses the Map Control

You can freely use the Map control during the testing phase, but when you submit it to the Store, you’ll need production credentials.

The credentials can be obtained during the submission process. One of the optional steps is called Map service, which will give you two codes called ApplicationId and AuthenticationToken. Once you have the codes, you need to set them in the following way when the application starts:

Movement Sensors

Windows Phone devices have many movement sensors that can be used by applications, like the accelerometer, gyroscope, and compass. The Windows Runtime has introduced a new set of APIs which are part of the Windows.Devices.Sensors namespace:

  • The Accelerometer class can be used to interact with the accelerometer.
  • The Gyrometer class can be used to interact with the gyroscope.
  • The Compass class can be used to interact with the compass.
  • OrientationSensor is a special class that can combine values obtained from all the available sensors.

Note: To use sensors, you’ll need to enable the ID_CAP_SENSORS option in the manifest file. If you also want to use gyroscope and compass, you need to enable the ID_REQ_MAGNETOMETER and ID_REQ_GYROSCOPE capabilities in the Requirements section of the manifest file. This way, users with devices without one of these sensors won’t be able to download your application.

All the sensors work in the same way. You’ll be able to get a reference to the sensor using the GetDefault() method. If it’s not available on the phone (for example, not all devices have a gyroscope), you’ll get a null reference in return. It’s important to always check if the returned sensor is null before doing any operation.

Like the geolocation services, you have two ways to interact with sensors:

  • the GetCurrentReading() method, which returns a single detection
  • the ReadingChanged event handler, which is triggered every time the phone moves to a new position

In this section, we’ll use as an example the OrientationSensor class, which is a special sensor that is able to combine all the values returned by the available sensors and automatically filter all the out-of-scale data. The class returns an OrientationSensorReading object, which contains all the information about the current position. You’ll be able to get the device position by using the Quaternion and RotationMatrix properties. 

In the following samples, you can see two ways to achieve the same result: getting a single reading, and subscribing to notifications that are sent every time the position changes. The device’s coordinates on the x-axis, y-axis, and z-axis are displayed on the screen using three TextBlock controls:

Please note that if you decide to subscribe to the ReadingChanged event, you’ll need a Dispatcher to communicate with the user interface since the event handler is managed by a background thread.

If you need to use a specific sensor, the code to use is very similar. You’ll simply have to use the specific sensor class and manage the specific reading object that you’ll get in return.

Tip: The Windows Phone emulator features a tool to simulate movement sensors. Unfortunately, only the accelerometer is supported; for every other sensor, including the OrientationSensor, you’ll need a real device.

Determining the Current Hardware

Windows Phone offers a class called DeviceStatus that can be used to get information about the current device, like:

  • the firmware version, with the DeviceFirmwareVersion property
  • the hardware version, with the DeviceHardwareVersion property
  • the manufacturer, with the DeviceManufacturer property
  • the device name, with the DeviceName property
  • the amount of total memory available, with the DeviceTotalMemory property

Plus, you have access to some useful APIs to get the current status of the battery. They belong to the Windows.Phone.Devices.Power namespace, and you’ll be able to use the Battery class to identify the percentage of remaining battery charge (with the RemainingChargePercent property) and the remaining time before the battery totally discharges (with the RemainingDischargeTime property).

The Battery class behaves like a sensor; you’ll have to use the GetDefault() method to get a reference to it (even if, in this case, you can avoid checking whether the returned object is null since every phone has a battery), as in the following sample:

In addition, the DeviceStatus class offers a property called PowerSource, which tells you the current power source, and an event handler, called PowerSourceChanged, which is triggered every time the current power source changes (from battery to external or vice versa).

It can be useful if, for example, you want to avoid performing power-consuming operations if the phone is not connected to an external power source.

Note: To get access to hardware info, you’ll need to enable the ID_CAP_IDENTITY_DEVICE capability in the manifest file.

Proximity

Under the proximity category we can include all the new APIs that have been introduced in the Windows Runtime to connect two devices together without using an Internet connection. In Windows Phone you can achieve this result by using two technologies: Bluetooth and NFC.

Bluetooth is well known and can be used to connect devices within a range of 10 meters. It’s been available since the first Windows Phone release, but only Windows Phone 8 has introduced APIs that are available to developers.

NFC is a more recent technology that has started to gain some traction in recent years. It can be used to exchange small amounts of data within a close range (the two devices should basically touch each other). NFC is an interesting technology since it works not only with active devices (like two phones), but also with passive devices (like chips embedded in a sticker or in a magazine page). In addition, Windows Phone is able to extend NFC and use it also to create a Bluetooth communication channel without needing to manually pair the two devices. This way, you can overcome NFC’s limitations and use Bluetooth to transfer larger data files, like images.

Note: To use Proximity APIs, you’ll need to enable the ID_CAP_PROXIMITY option in the manifest file.

The easiest way to test applications that use the Proximity APIs is with real devices, but there’s also a third-party tool called Proximity Tapper available on CodePlex that can be used to simulate the connection between different emulators (since Visual Studio is able to run only one specific emulator at a time, you’ll have to use different emulator versions, for example a WVGA and a WXGA one).

Exchanging Messages

A common scenario when working with NFC is the exchange of messages, which represents a small amount of data. There are some standard messages that Windows Phone is able to manage automatically (for example, when you receive a URI or a contact), and some custom messages which can be managed only by third-party apps.

The first step, as with every other sensor we’ve seen so far, is to use the GetDefault() method of the ProximityDevice class to get access to the proximity sensor. In this case, we also need to check if the sensor reference is null before moving on, since some devices don’t support NFC.

Every message is identified by a specific keyword. The Windows Phone APIs natively support three message types—text, URI, and binary. Let’s see how to manage them.

Text Messages

Publishing a text message is easy. We use the PublishMessage() method of the ProximityDevice class, which requires the message type and the content as parameters. In the following sample, you can see how we send a text message, identified by the Windows.SampleMessage keyword.

As you can see, the PublishMessage() method accepts a third, optional parameter, which is an event that is raised when the message has been received by the other device. This event can be useful, as shown in the previous sample, to stop sending the message once it has been received by calling the StopPublishingMessage() method on the ProximityDevice object. You need to set the message ID, which is passed as a parameter of the method.

The phone receiving the message should instead call the SubscribeForMessage() method. Unlike the publishing method, this method is the same regardless of the data we expect. The difference is that, according to the message, we can use some specific properties to parse it and extract the information we need.

In the following sample you can see how it’s easy to extract the message content thanks to the DataAsString property of the ProximityMessage class:

This code is not very different from the code used to send the message; the SubscribeForMessage() method requires the message type and the event handler that is invoked when the message has been received.

The message is received thanks to the ProximityMessage object that is returned as a parameter. In this case, since it’s a text message, we can extract the content using the DataAsString property. Note that again in this situation we cancel the subscription by using the StopSubscribingForMessage() method so that the application won’t listen anymore for the incoming message.

URI

Sending URIs works in a similar way, except that we need to use the PublishUriMessage() method that accepts the Uri to send as a parameter. In this case, we don’t need to set the message type since it’s implicit.

The difference is that Uri messages are directly supported by Windows Phone, so you’ll be able to exchange them without using a receiver application. The operating system, once it has received the Uri, will simply ask the user if he or she wants to open the browser to see it.

However, if you still want to manage Uris in your application, you can subscribe to receive them. In this case, you’ll have to listen for the incoming WindowsUri message. In addition, you’ll need some more code to extract it since it’s not treated as a string; you’ll need to work directly with a byte array, as in the following sample:

NDEF Messages

NDEF (NFC Data Exchange Format) is a standard protocol used to define NFC messages that can be used to exchange different data types across different platforms. Some common scenarios are exchanging geolocation data, mail sending, and social network sharing.

NDEF isn’t natively supported by Windows Phone APIs. To avoid requiring developers to manually create the binary data needed to compose a message, a developer named Andreas Jakl has created a library called NDEF Library For Proximity API, which is available on CodePlex and can be easily installed using NuGet.

This library features many classes that encapsulate the needed logic for the most common messages, like NdefGeoRecord for sharing geolocation coordinates, NdefLaunchAppRecord to open another Windows Phone application, and NdefTelRecord to start a phone call to a specific number. You can see a complete list of the supported records on the official website.

In the following sample, you’ll see how to send a message that contains an NdefSmsRecord which can be used to create a new SMS message with predefined text:

The first step is to create the record and set the needed properties. In this sample, we need to set the SmsNumber (the phone number that will receive the message) and SmsBody (the message’s text) properties.

Next, we need to encapsulate the record into a new message, which is identified by the NdefMessage class. In the end, we can send it; in this scenario we need to use the PublishBinaryMessage() method of the ProximityDevice class, since it’s not a standard message but a binary one. As you can see, we pass as parameter (other than the message’s type, which is NDEF) the message as a bytes array.

If the message’s type is natively supported by Windows Phone, the device will automatically manage the incoming message. With the previous sample, the operating system will prompt to the user to send a SMS message. Instead, if we want to receive it within an application, we’ll need to do some additional work. Since it’s a binary message, we’ll need to extract the needed information. Fortunately, the NDEF Library for Proximity API will help us, as you can see in the following sample:

We need to subscribe for incoming NDEF messages. When we receive the message, we are able to convert the binary data (which is available in the Data property of the ProximityMessage class) into a NdefMessage again, thanks to the FromByteArray() method.

An NdefMessage object can contain more than one record, so we need to iterate it and extract every NdefRecord object that is stored. In the previous sample, since we expect to only get an NdefSmsRecord, we manage only this scenario. The task is accomplished by using the CheckSpecializedType() method on the record, which returns its data type. We manage it only if it’s the type we’re expecting. We are able to get the original record simply by creating a new NdefSmsRecord object and passing, as a parameter, the NdefRecord object stored in the message.

Once we have it, we are able to access all its properties. In the previous sample, we show the user the body of the SMS message.

Writing Messages to a Tag

As mentioned previously, NFC can be used with passive devices, like tags and stickers. Windows Phone devices are able to write data to NFC tags simply by adding the :WriteTag suffix to the message’s type when publishing a message.

In the following code you can see how to adapt the previous sample to write the record into a tag instead of sending it to another device:

Creating a Communication Channel Using NFC

As previously mentioned, NFC can be used only to exchange small amounts of data—it can’t be used to maintain a stable communication channel. The best technology to achieve this result is Bluetooth. However, we’re able to use NFC as a shortcut to establish a Bluetooth channel between two devices that have the same installed application.

Note: In this case we also need to enable the ID_CAP_NETWORKING option in the manifest file.

The starting point is the PeerFinder class, which can be used (on both devices) to start the connection and look for another device to pair with. Using it is quite simple: you have to subscribe to the TriggeredConnectionStateChanged event that is triggered when the connection status changes, and start the pairing process by calling the Start() method.

You’ll need to use the same code on both devices. However, there’s a work-around to automatically execute it in case the app is opened by a pairing request. In fact, when you execute the previous code and connect the two devices together, Windows Phone will automatically intercept the incoming message and will prompt the user to open the required application. When this happens, the application is opened with the following special URI:

By using the OnNavigatedTo event on the main page we are able to intercept this special URI and automatically start the pairing process, as shown in the following sample:

The TriggeredConnectionStateChanged event can be used to manage the actual connection status. The most important state is Completed, which is triggered when the connection has been successfully established and you can start to exchange data.

In the following sample, you can see that once the connection is established, we store the channel (identified by a StreamSocket object) in another variable to be used later for further communications.

Other than saving a reference to the channel, we start listening for incoming messages (we’ll see how in a moment) and we call the Stop() method of the PeerFinder class. Since the channel has been created, we can stop the pairing process.

Listening for Incoming Messages

The listening process works in a way similar to polling; until the channel is opened, we keep asking the other device if there’s a new message. In the following sample, we exchange text messages by using the DataReader and DataWriter classes we learned to use earlier in this series in the context of storing data in the local storage.

While the channel is opened and the listening process is active, we keep calling the GetMessage() method. If there’s an incoming message in the channel, we display it to the user. The polling procedure is implemented using a while loop, which is repeated until the isListening variable is set to true.

The GetMessage() method is simply a helper that, by using the DataReader class, is able to get the channel’s data (which is stored as binary in the InputStream property of the StreamSocket class) and convert it into a plain string.

Sending a Message

To send a message, we need to use the DataWriter class to write the data in the OutputStream channel of the StreamSocket object. We have to send two pieces of information: the message size by using the WriteInt32() method, and the message text by using the WriteString() message.

If you want to send a message on the channel, it’s enough to use the SendMessage() method we’ve just defined:

Creating a Communication Channel Using Bluetooth

The approach to creating a communication channel using Bluetooth is the same we’ve previously seen. A channel is identified by the StreamSocket class, and we can send and listen for incoming messages exactly in the same way.

What changes is the way we connect to another device. With NFC, the peer-to-peer communication is necessarily made between the two devices that are connected. With Bluetooth, instead, you can virtually connect to any device within your phone’s range. 

We’re going to use the PeerFinder class again, but this time, instead of starting the pairing process using the Start() method, we look for all the available peers with the FindAllPeersAsync() method. It returns a collection of PeerInformation objects—each one is a device that can connect with our application.

In the following sample, we simply display the list of available devices to the user, by setting the collection as ItemsSource of a ListBox control:

Notice that we’ve embedded our code into a try/catch statement; in fact, the user may have Bluetooth turned off. While we start looking for other peers, if we get an exception with the error code 0x8008048F, it means that we are in this situation, so we have to properly manage it (for example, by informing the user that he or she needs to turn it on to use the application).

After the user has chosen which device he or she wants to connect with, we need to call the ConnectAsync() method of the PeerFinder class, passing the PeerInformation object that represents the device as a parameter. Next, exactly like we did for the NFC communication, we start listening for messages and stop looking for other peers using the Stop() method, as shown in the following sample:

The StartListeningForMessage() method is the same method we used to deal with NFC communication.

On the other side (the phone that the user has selected to interact with), if we want to accept the incoming communication request from another phone, we need to again use the Start() method of the PeerFinder class and subscribe to the ConnectionRequested event, which is triggered when another device has requested to establish a connection.

In the event handler we simply have to call the ConnectAsync() method of the PeerFinder class like we did with the phone that started the connection request. We’ll get a reference to the device that sent the request in the method’s parameters.

Conclusion

In this article we’ve seen how to interact with the hardware features that every Windows Phone device has. Specifically:

  • We’ve seen how to interact with the geolocation services, retrieve the user’s location, and interact with the Map control.
  • We’ve learned how to use the motion sensors to determine the device’s position in space. It’s a feature particularly useful with games, since many of them are easier to control with the accelerometer rather than with virtual controls.
  • We’ve briefly covered the hardware APIs that are useful for obtaining information about the device on which the app is running.
  • We’ve discussed Proximity APIs, which have been introduced in the Windows Runtime to connect two devices without requiring an Internet connection. Specifically, we’ve talked about two technologies: NFC and Bluetooth.
2015-03-26T19:13:12.000Z2015-03-26T19:13:12.000ZMatteo Pagani
Viewing all 1836 articles
Browse latest View live