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

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

Viewing all articles
Browse latest Browse all 1836

Trending Articles