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

Windows Phone 8 Succinctly: Tiles, Notifications, and Multitasking

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

In this tutorial, we're going to focus on live apps. Live apps are one of the core concepts in Windows Phone development, and to properly create a quality experience, many factors are involved, like notifications, agents, and Tiles.

The Multitasking Approach

As we’ve seen in the application life cycle discussed earlier in this series, applications are suspended when they are not in the foreground. Every running process is terminated, so the application can’t execute operations while in the background.

There are three ways to overcome this limitation:

  • Push notifications, which are sent by a remote service using an HTTP channel. This approach is used to send notifications to users, update a Tile, or warn users that something has happened.
  • Background agents, which are services connected to our application that can run from time to time under specific conditions. These services can also be used for push notification scenarios—in this case, remote services are not involved—but they can also perform other tasks as long as they use supported APIs.
  • Alarms and reminders, which display reminders to the user at specific dates and times.

Let’s see in detail how they work.

Push Notifications

Push notifications are messages sent to the phone that can react in many ways based on the notification type. There are three types of push notifications:

  • Raw notifications can store any type of information, but they can be received only if the associated application is in the foreground.
  • Toast notifications are the most intrusive ones, since they display a message at the top of the screen, along with a sound and a vibration. Text messages are a good example of toast notifications.
  • Tile notifications can be used to update the application’s Tile.

There are three factors involved in the push notification architecture:

  • The Windows Phone application, which acts as a client to receive notifications.
  • The server application, which can be a web application or a service, that takes care of sending the notifications. Usually, the server stores a list of all the devices that are registered to receive notifications.
  • The Microsoft Push Notification Service (MPNS), which is a cloud service offered by Microsoft that is able to receive notifications from the server application and route them to the Windows Phone clients.
Microsofts Push Notification Architecture

Every Windows Phone application receives push notifications using a channel, which is identified by a unique URI. The server application will send notifications to the registered clients by sending an XML string to this URI using a POST command. The MPNS will take care of routing the requests to the proper devices.

Here is a sample of a URI that represents a channel:

Note: MPNS usage is free, but limited to 500 notifications per day per single device. If you need to exceed this limitation, you have to buy a TLS digital certificate, which you’ll need to submit during the certification process and to digitally sign your server’s application. This way, you’ll also be able to support SSL to encrypt the notification’s channel.

Sending a Notification: The Server

As already mentioned, notifications are sent using an HTTP channel with a POST command. The benefit is that it relies on standard technology, so you’ll be able to create a server application with any development platform.

The HTTP request that represents a notification has the following features:

  • It’s defined using XML, so the content type of the request should be text/xml.
  • A custom header called X-WindowsPhone-Target, which contains the notification’s type (toast, Tile, or raw).
  • A custom header called X-NotificationClass, which is the notification’s priority (we’ll discuss this more in-depth later).

Let’s see how the different push notifications are structured in detail.

Toast Notifications

The following sample shows the XML needed to send a toast notification:

There are three parameters to set:

  • wp:Text1 is the notification’s title.
  • wp:Text2 is the notification’s text.
  • wp:Param is the optional notification deep link; when this is set, the application is opened automatically on the specified page with one or more query string parameters that can be used to identify the notification’s context.

When you prepare the request to send over HTTP, the X-WindowsPhone-Target header should be set to toast, while the X-NotificationClass header supports the following values:

  • 2 to send the notification immediately.
  • 12 to send the notification after 450 seconds.
  • 22 to send the notification after 900 seconds.
A Toast Notification

Tile Notifications

Tile notifications are used to update either the main Tile or one of the secondary Tiles of the application. We won’t describe the XML needed to send the notification here: Tiles are more complex than the other notification types since Windows Phone 8 supports many templates and sizes. We’ll look at the XML that describes Tile notifications later in the Tiles section of the article.

To send a Tile notification, the X-WindowsPhone-Target header of the HTTP request should be set to tile, while the X-NotificationClass header supports the following values:

  • 1 to send the notification immediately.
  • 11 to send the notification after 450 seconds.
  • 21 to send the notification after 900 seconds.

Raw Notifications

Raw notifications don’t have a specific XML definition since they can deliver any kind of data, so we can include our own definition.

To send a raw notification, the X-WindowsPhone-Target header of the HTTP request should be set to raw, while the X-NotificationClass header supports the following values:

  • 3 to send the notification immediately.
  • 13 to send the notification after 450 seconds.
  • 23 to send the notification after 900 seconds.

Sending the Request and Managing the Response

The following sample code shows an example of how to send a toast notification using the HttpWebRequest class, one of the basic .NET Framework classes for performing network operations:

The XML definition is simply stored in a string. We’re going to change just the node values that store the notification’s title and text. Then, we start to prepare the HTTP request by using the HttpWebRequest class. We add the custom headers, define the content’s length and type (text/xml), and specify the method to use (POST).

In the end, by using the GetRequestStream() method, we get the stream location to write the request’s content, which is the notification’s XML. Then we send it by calling the GetResponse() method, which returns the status of the request. By analyzing the response we are able to tell whether or not the operation was successful. 

The response’s analysis involves the status code and three custom headers:

  • The response’s status code returns generic information that tells you whether the request has been received. It’s based on the standard HTTP status codes. For example, 200 OK means that the request has been successfully received, while 404 Not Found means that the URI was invalid.
  • The X-NotificationStatus header tells you if the MPNS has received the request using the values Received, Dropped, QueueFull, and Supressed.
  • The X-DeviceConnectionStatus header returns the device status when the request is sent: Connected, Inactive, Disconnected, or TempDisconnected.
  • The X-SubscriptionStatus header returns if the channel is still valid (Active) or not (Expired). In the second case, we shouldn’t try to send it again, since it doesn’t exist anymore.

The combination of these parameters will help you understand the real status of the operation. The MSDN documentation features descriptions of all the possible combinations.

It’s important to correctly manage the notifications because MPNS doesn’t offer any automatic retry mechanism. If a notification is not delivered, MPSN won’t try again to send it, even if the operation failed for a temporary reason (for example, the device wasn’t connected to the Internet). It’s up to you to implement a retry mechanism based on the response.

PushSharp: A Push Notification Helper Library

As you can see, sending push notifications is a little bit tricky since it requires you to manually set headers, XML strings, etc. Some developers have worked on wrappers that hide the complexity of manually defining the notification by exposing high-level APIs so that you can work with classes and objects.

One of the most interesting wrappers is called PushSharp, which can be simply installed on your server project using NuGet. The biggest benefits of this library are:

  • It’s a generic .NET library that supports not only Windows Phone, but the most common platforms that use push notifications, like Windows Store apps, iOS, Android, and Blackberry. If you have a cross-platform application, it will make your life easier in managing a single-server application that is able to send notifications to different kinds of devices.
  • It’s totally compatible with Windows Phone 8, so it supports not only toast and raw notifications, but also all the new Tile templates and sizes.

The following sample shows how simple it is to send a toast notification using this library:

Every notification type is represented by a specific class, which exposes a property for every notification feature. In the previous sample, the WindowsPhoneToastNotification class offers properties to set the notification’s title, text, and deep link.

The channel URI location to send the notification is set in the EndPointUrl property. Once everything is set, you can send it by creating a PushBroker object, which represents the dispatcher that takes care of sending notifications. First, you have to register for the kind of notifications you want to send. Since we’re working with Windows Phone, we use the RegisterWindowsPhoneService() method. Then, we can queue the notification by simply passing it to the QueueNotification() method. It will be automatically sent with the priority you’ve set.

The approach is the same if you want to send a Tile. You have three different classes based on the Tile’s template, WindowsPhoneCycleTileNotification, WindowsPhoneFlipTileNotification, and WindowsPhoneIconicTileNotification; or WindowsPhoneRawNotification for a raw notification.

In the end, the PushBroker class exposes many events to control the notification life cycle, like OnNotificationSent which is triggered when a notification is successfully sent, or OnNotificationFailed which is triggered when the sending operation has failed.

Receiving Push Notifications: The Client

The base class that identifies a push notification channel is called HttpNotificationChannel and exposes many methods and events that are triggered when something connected to the channel happens.

Note: To receive push notifications you’ll need to enable the ID_CAP_PUSH_NOTIFICATION capability in the manifest file.

Every application has a single unique channel, identified by a keyword. For this reason, it should be created only the first time the application subscribes to receive notifications; if you try to create a channel that already exists, you’ll get an exception. To avoid this scenario, the HttpNotificationChannel class offers the Find() method, which returns a reference to the channel.

In the previous sample, the channel is created only if the Find() method fails and returns a null object. The HttpNotificationChannel class exposes many methods to start interacting with push notifications; they should be called only if the channel doesn’t already exist. In the sample we see the Open() method which should be called to effectively create the channel, and which automatically subscribes to raw notifications. 

If we want to be able to receive toast and Tile notifications, we need to use two other methods offered by the class: BindToShellToast() and BindToShellTile(). The following sample shows a complete initialization:

Beyond offering methods, the HttpNotificationChannel class also offers some events to manage different conditions that can be triggered during the channel life cycle.

The most important one is called ChannelUriUpdated, which is triggered when the channel creation operation is completed and the MPNS has returned the URI that identifies it. This is the event in which, in a regular application, we will send the URI to the server application so that it can store it for later use. It’s important to subscribe to this event whether the channel has just been created, or already exists and has been retrieved using the Find() method. From time to time, the URI that identifies the channel can expire. In this case, the ChannelUriUpdated event is triggered again to return the new URI.

The following sample shows a full client initialization:

As you can see, the ChannelUriUpdated event returns a parameter with the ChannelUri property, which contains the information we need. In the previous sample, we just display the URI channel to the user.

There are two other events offered by the HttpNotificationChannel class that can be useful:

  • HttpNotificationReceived is triggered when the application has received a raw notification.
  • ShellToastNotificationReceived is triggered when the application receives a toast notification while it is open. By default, toast notifications are not displayed if the associated application is in the foreground.

The HttpNotificationReceived event receives, in the parameters, the object that identifies the notification. The content is stored in the Body property, which is a stream since raw notifications can store any type of data. In the following sample, we assume that the raw notification contains text and display it when it’s received:

The ShellNotificationReceived event, instead, returns in the parameters a Collection object, which contains all the XML nodes that are part of the notification. The following sample shows you how to extract the title and the description of the notification, and how to display them to the user:

Managing Errors

If something goes wrong when you open a notification channel, you can subscribe to the ErrorOccurred event of the HttpNotificationChannel class to discover what’s happened.

The event returns a parameter that contains information about the error, like ErrorType, ErrorCode, ErrorAdditionalData, and Message.

The following list includes the most common conditions that can lead to a failure during the channel opening:

  • To preserve battery life and performance, Windows Phone limits the maximum number of channels that are kept alive at the same time. If the limit has been reached and you try to open a new channel, you’ll get the value ChannelOpenFailed as ErrorType.
  • The received notification can contain a message which is badly formatted; in this case the ErrorType will be MessageBadContent.
  • You can send too many notifications at the same time; in this case, they are rejected with the NotificationRateTooHigh error.
  • To preserve battery power, notifications can be received only if the battery isn’t critical; in this case, you’ll get a PowerLevelChanged error.

The ErrorAdditionalData property can contain additional information about the error. For example, if you get a PowerLevelChanged error, you’ll be informed of the current battery level (low, critical, or normal).

Background Agents

Push notifications are the best way to interact with the user when the application is not running since they offer the best experience and, at the same time, preserve battery life. However, the experience is limited to notifications: you can’t execute any other operation, like fetching data from a web service or reading a file from the local storage. Moreover, for certain scenarios in which you don’t require instant notifications, creating the required server infrastructure can be too expensive. Think, for example, of a weather application: it’s not critical that the forecast is updated immediately when the forecasts change.

For all these scenarios, Windows Phone 7.5 has introduced background agents, which are special services periodically executed by Windows Phone, even when the application is not running. There are two types of periodic background agents: periodic and audio. In the New Project section of Visual Studio, you’ll find many templates for all the supported agent types. In this section we’ll see how periodic agents work in detail.

Tip: Even if a background agent is a separate Visual Studio project, it shares the same resources with the foreground application. For example, they share the same local storage, so you’re able to read data created by the application in the agent, and vice versa.

Agent Limits

There are some limitations that background agents have to satisfy. The most important one is connected to timing, since agents can run only in a specific time frame for a limited amount of time. We’ll discuss this limitation later since there are some differences according to the background agent type you’re going to use.

The first limitation concerns supported APIs: only a limited number of APIs can be used in a background agent. Basically, all the APIs that are related to the user interface are prohibited since agents can’t interact with the application interface. You can find the complete list of unsupported APIs in the MSDN documentation.

The second limitation is about memory: a background agent can’t use more than 11 MB of memory, otherwise it will be terminated. It’s important to highlight that during the testing process (when the Visual Studio debugger is attached), the memory limit will be disabled, and the background agent won’t be terminated if it has used more than 11 MB. You’ll have to test it in a real environment if you want to make sure the limit isn’t reached.

The third and final limitation is about timing: a background agent is automatically disabled 14 days after it has been initialized by the connected application. There are two ways to overcome this limitation:

  • The user keeps using the application; the agent can be renewed for another 14 days every time the application is opened.
  • The agent is used to send notifications to update the main application’s Tile or the lock screen; every time the agent sends a notification it will be automatically renewed for another 14 days.

It’s important to keep in mind that if the background agent execution consecutively fails twice (because it exceeded the memory limit or raised an unmanaged exception), it’s automatically disabled; the application will have to reenable it when it’s launched.

Periodic Agents

Periodic agents are used when you need to execute small operations frequently. They are typically executed every 30 minutes (the execution interval can sometimes be shortened to every 10 minutes to coincide with other background processes to save battery life), and they can run for up to 25 seconds. Users are able to manage periodic agents from the Settings panel and disable the ones they don’t need. Periodic agents are automatically disabled if the phone is running in Battery Saver mode; they’ll be automatically restored when sufficient battery power is available.

Periodic agents are identified by the PeriodicTask class, which belongs to the Microsoft.Phone.Scheduler namespace.

Resource Intensive Agents

Resource intensive agents have been created for the opposite scenario: long-running tasks that are executed occasionally. They can run for up to 10 minutes, but only if the phone is connected to a Wi-Fi network and an external power source.

These agents are perfect for tasks like data synchronization. In fact, they are typically executed during the night, when the phone charging. Other than the previous conditions, in fact, the phone shouldn’t be in use. The lock screen should be activated and no other operations (like phone calls) should be performing.

Resource intensive agents are identified by the ResourceIntensiveTask, which is also part of the Microsoft.Phone.Scheduler namespace.

Creating a Background Agent

As already mentioned, background agents are defined in a project separate from the front-end application. Periodic agents share the same template and architecture, and the Windows Phone application will decide to register them as PeriodicTask or ResourceIntensiveTask objects.

To create a background agent, you’ll have to add a new project to the solution that contains your Windows Phone application. In the Add New Project window you’ll find a template called Windows Phone Scheduled Task Agent in the Windows Phone section.

The project already contains the class that will manage the agent; it’s called ScheduledAgent and it inherits from the ScheduledTaskAgent class. The class already implements a method and an event handler.

The method, called OnInvoke(), is the most important one. It’s the method that is triggered when the background agent is executed, so it contains the logic that performs the operations we need. The following sample shows how to send a toast notification from a background agent:

It’s important to highlight the NotifyComplete() method, which should be called as soon as the agent has completed all the operations. It notifies the operating system that the task has completed its job and that the next scheduled task can be executed. The NotifyComplete() method determines the task’s status. If it’s not called within the assigned time—25 seconds for periodic tasks or 10 minutes for resource intensive tasks—the execution is interrupted.

There’s another way to complete the agent’s execution: Abort(). This method is called when something goes wrong (for example, the required conditions to execute the agent are not satisfied) and the user needs to open the application to fix the problem.

The event handler is called UnhandledException and is triggered when an unexpected exception is raised. You can use it, for example, to log the error.

The previous sample shows you how to send local toast notifications. A toast notification is identified by the ShellToast class. You simply have to set all the supported properties (Title, Content, and optionally NavigationUri, which is the deep link). In the end, you have to call the Show() method to display it.

Like remote notifications, local toasts are supported only if the application is in the background. The previous code works only inside a background agent. If it’s executed by a foreground application, nothing happens.

Registering the Agent

The background agent is defined in a separate project, but is registered in the application. The registration should be done when the application starts, or in the settings page if we give users the option to enable or disable it within the application.

The base class to use when working with background agents is ScheduledActionService, which represents the phone’s scheduler. It takes care of registering all the background agents and maintaining them during their life cycle.

The first step is to define which type of agent you want to use. As previously mentioned, the background agent architecture is always the same; the type (periodic or resource intensive) is defined by the application.

In the first case you’ll need to create a PeriodicTask object, and in the second case, a ResourceIntensive task object. Regardless of the type, it’s important to set the Description property, which is text displayed to users in the Settings page. It’s used to explain the purpose of the agent so users can decide whether or not to keep it enabled.

In both cases, background agents are identified by a name, which is passed as a parameter of the class. This name should be unique across all the tasks registered using the PhoneApplicationService class; otherwise you’ll get an exception.

The basic operation to add a task is very simple:

The first operation checks whether the agent is already scheduled by using the Find() method of the ScheduledActionService class, which requires the task’s unique name. This operation is required if we want to extend the agent’s lifetime. If the agent does not exist yet or is not scheduled (the IsScheduled property is false), we first remove it from the scheduler and then add it since the ScheduledActionService class doesn’t offer a method to simply update a registered task. The add operation is done using the Add() method, which accepts either a PeriodicTask or a ResourceIntensiveTask object.

Now the task is scheduled and will be executed when the appropriate conditions are satisfied. If you’re in the testing phase, you’ll find the LaunchForTest() method useful; it forces the execution of an agent after a fixed amount of time. In the previous sample, the agent identified by the name PeriodicTask is launched after five seconds. The LaunchForTest() method can also be executed in the OnInvoke() event inside the background agent, allowing you to easily simulate multiple executions.

In the previous sample you can see that we’ve used conditional compilation to execute the LaunchForTest() method only when the application is launched in debug mode. This way, we make sure that when the application is compiled in release mode for publication to the Windows Store, the method won’t be executed; otherwise, you’ll get an exception if the method is called by an application installed from the Store.

Managing Errors

Background agents are good examples of the philosophy behind Windows Phone:

  • Users are always in control; they can disable whatever background agents they aren’t interested in through the Settings page.
  • Performance and battery life are two crucial factors; Windows Phone limits the maximum number of registered background agents.

For these reasons, the agent registration process can fail, so we need to manage both scenarios. The following code shows a more complete sample of a background agent’s initialization:

The difference in the previous sample is that the Add() operation is executed inside a try / catch block. This way, we are ready to catch the InvalidOperationException error that might be raised.

We can identify the scenario by the exception message:

  • BNS Error: The action is disabled. The user has disabled the agent connected to our application in the Settings page. In this case, we have to warn the user to enable it again in the Settings page before trying to register it.
  • BSN Error: The maximum number of ScheduledActions of this type have already been added. The user has reached the maximum number of agents allowed to be installed on phone. In this case, we don’t have to do anything; Windows Phone will display a proper warning message.
A Background Agent Disabled by the User in the Settings Page

Moreover, the ScheduledTask class (which is the base class that PeriodicTask and ResourceIntensiveTask inherit from) offers some properties for understanding the status of the last execution, such as LastScheduledTime which contains the date and time of the last execution, and LastExitReason which stores the last execution status.

Specifically, LastExitReason is very useful for knowing if the last execution completed successfully (Completed), if it exceeded the memory limit (MemoryQuotaExceeded) or the time limit (ExecutionTimeExceeded), or if an unhandled exception occurred (UnhandledException).

Background Audio Agent

There’s a special kind of background agent that works differently than periodic agents: audio agents, which are used in audio-related applications to keep playing audio when the app is closed. The goal is to offer a similar experience to the native Music + Videos Hub; even when the app is not in the foreground, users are able to keep listening to their music library.

A Background Audio Player

Again, the background agent is defined in a different project than the foreground application. However: 

  • The agent doesn’t need to be initialized in the foreground application using the ScheduledActionService class like we did for periodic agents.
  • There aren’t time limitations. The agent runs every time users interact with the music controls, and it never expires. The only limitation is that the triggered operation should complete within 30 seconds.
  • There is a memory limitation, but the cap is higher: 20 MB (keep in mind that the memory limit isn’t activated when the Visual Studio debugger is connected).
  • In this scenario, the background agent is not just a companion, but the core of the application; it manages all interactions with the music playback, regardless of whether they occur in the foreground application or the native embedded player.

Interacting With the Audio

The core class to reproduce background audio is called BackgroundAudioPlayer, which identifies the built-in Windows Phone audio player. There’s just one instance of the player within the system, and it can’t be shared. If users launch another application that uses a background audio agent (including the native Music + Videos Hub), it takes control over the audio reproduction. As we’re going to see soon, the BackgroundAudioPlayer class is used both in the foreground app and in the background agent to interact with the music playback.

The audio tracks played by a background audio agent are represented by the AudioTrack class. Each track, other than the resource to play, contains all the metadata like the title, artist, and album title.

The track’s path is set in the Source property, which can be either a remote file or a file stored in the local storage. However, most of the properties can be set directly when the AudioTrack object is created, like in the following sample:

With the previous code, in addition to setting the source file, we also immediately set information like the title, the artist, and the album. A useful available property is called PlayerControls, which can be used to set which controls (Play, Pause, Forward, etc.) are available for the track. This way, if you’re developing an application connected to an online radio, for example, you can automatically block options that are not supported (like the skip track button).

Creating the Agent

Visual Studio offers two templates to create background audio agents: Windows Phone Audio Playback Agent and Windows Phone Audio Streaming agent. They share the same purpose; their difference is that the Windows Phone Audio Streaming agent is required for working with media streaming codecs that are not natively supported by the platform.

A background audio agent’s project already comes with a class called AudioAgent, which inherits from the AudioPlayerAgent class. As we saw with periodic agents, the class automatically implements some methods that are used to interact with the agent. The most important ones are OnUserAction() and OnPlayStateChanged().

OnUserAction() is triggered every time users manually interact with the music playback, such as pausing a track or pressing the skip track button in the foreground application or the background player.

The method returns some parameters that can be used to understand the context and perform the appropriate operations:

  • a BackgroundAudioPlayer object, which is a reference to the background audio player
  • an AudioTrack object, which is a reference to the track currently playing
  • a UserAction object, which is the action triggered by the user

The following sample shows a typical implementation of the OnUserAction() method:

Usually with a switch statement, you’ll monitor every supported user interaction, which is stored in the UserAction object. Then, you respond using the methods exposed by the BackgroundAudioPlayer class. Play and Pause are the simplest states to manage; SkipNext and SkipPrevious usually require more logic, since you have to get the previous or next track to play in the list from your library.

Note that background audio agents also require the NotifyComplete() method execution as soon as we’ve finished to manage the operation; it should be called within 30 seconds to avoid termination.

The OnPlayStateChanged() method is triggered automatically every time the music playback state is changed, but not as a direct consequence of a manual action. For example, when the current track ends, the agent should automatically start playing the next track in the list.

The method’s structure is very similar to the OnUserAction() method. In addition to a reference to the background player and the current track in this case, you’ll get a PlayState object, which notifies you about what’s going on.

The following sample shows a typical implementation of the method:

Tip: Background audio agents are not kept in memory all the time, but instead are launched only when the music playback state changes. If you need to persist some data across the different executions, you’ll need to rely on the local storage.

The Foreground Application

We’ve seen how all the main playback logic is managed directly by the background agent. The foreground application, in most of the cases, is just a visual front end for the agent.

To understand the playback state (and to properly update the UI) we need to use, again, the BackgroundAudioPlayer class we’ve seen. The difference is that, in the foreground application, we need to use the Instance singleton to get access to it.

The methods exposed by the class are the same, so we can use it to play, pause, or change the music playback state (for example, if we want to connect these operations to input controls like buttons).

The BackgroundAudioPlayer exposes an important event called PlayStateChanged, which is triggered every time the playback state changes. We can use it to update the visual interface (for example, if we want to display the track currently playing).

The following sample shows how the PlayStateChanged event is used to change the behavior of the play/pause button and to display to some metadata about the currently playing track:

The previous code should be familiar; you have access to all the properties we’ve seen in the background agent, like PlayerState to identify the current playback state, or Track to identify the currently playing track. Track isn’t just a read-only property. If we want to set a new track to play in the application, we can simply assign a new AudioTrack object to the Track property of the BackgroundAudioPlayer instance.

Alarms and Reminders

Alarms and reminders are simple ways to show reminders to users at a specified date and time, as the native Alarm and Calendar applications do.

They work in the same way. The APIs belong to the Microsoft.Phone.Scheduler namespace, and they inherit from the base ScheduledNotification class. There are some properties in common between the two APIs:

  • Content: The reminder description.
  • BeginTime: The date and time the reminder should be displayed.
  • RecurrenceType: Sets whether it’s a recurrent or one-time reminder.
  • ExpirationTime: The date and time a recurrent reminder expires.

Every reminder is identified by a name, which should be unique across all the alarms and reminders created by the application. They work like background agents; their life cycle is controlled by the ScheduledActionService class, which takes care of adding, updating, and removing them.

Alarms are identified by the Alarm class and used when to show a reminder that doesn’t have a specific context. Users will be able to snooze or dismiss it. A feature specific to alarms is that they can play a custom sound, which is set in the Sound property.

The following sample shows how to create and schedule an alarm:

The sample creates an alarm that is scheduled 15 seconds after the current date and time, and uses a custom sound that is an MP3 file inside the Visual Studio project.

Reminders, instead, are identified by the Reminder class and are used when the notification is connected to a specific context, in a similar way that calendar reminders are connected to an appointment.

The context is managed using the NavigationUri property, which supports a deep link. It’s the page (with optional query string parameters) that is opened when users tap the reminder’s title.

The previous code schedules a reminder that opens a page called DetailPage.xaml. Using the navigation events described earlier in this series, you’ll be able to get the query string parameters and load the requested data. Notice also that the Reminder class offers a Title property, which is not supported by alarms.

Live Tiles

Live Tiles are, without a doubt, the most unique Windows Phone feature, and one you won’t find on any other platform. They are called Live Tiles because they aren’t simply shortcuts to open applications; they can be updated with local or remote notifications to display information without forcing users to open the application. Many kinds of applications take advantage of this feature, like weather apps that display the forecast, news apps that display the latest headlines, and movie apps that display upcoming movie titles.

Windows Phone 8 has introduced many new features regarding Tiles, like new templates and new sizes.

An application can use three different sizes for Tiles: small, medium, and wide. As developers, we’ll be able to customize the Tile’s content according to the size so that, for example, the wide Tile can display more info than the small Tile.

Various Tile Sizes

Windows Phone 8 has also introduced three different templates to customize a Tile: flip, cycle, and iconic. It’s important to note that you can choose only one template for your application; it must be declared in the manifest file, in the Application UI section. Once you’ve set it, you won’t be able to change it at run time, and all the Tiles you’re going to create or update will have to use that template. In addition, you can choose the features (Tiles, pictures, etc.) to use for the main Tile in the Application UI section; this information will be used until a notification updates it.

In the following sections we’ll examine every available template in detail. For each one we’ll discuss the architecture and code needed to update it with a notification. For remote notifications, we’ll see the required XML. For local notifications, we’ll look at the APIs to use in the application or in a background agent.

In both cases, all the fields that define a Tile are optional. If you don’t set some of them, those properties will simply be ignored. On the other hand, if a field that was previously set is not updated with a notification, the old value will be kept.

Flip Template

Flip is the standard Windows Phone template, and the only one that was already available in Windows Phone 7. With this template you can display text, counters, and images on the front of the Tile. Periodically, the Tile will rotate or “flip” to show the opposite side, which can display different text or images.

Anatomy of a Tile Using the Flip Template

As you can see from the previous figure, you can customize both front and rear sides of the Tile. If you want to include an image, you have to use one of the following sizes:

  • Small: 159 × 159
  • Medium: 336 × 336
  • Wide: 691 × 336 

A flip template Tile is identified by the FlipTileData class. The following sample shows how to use it to define a Tile that can be managed by code.

The following code shows how the same Tile is represented using the XML definition needed for remote notifications:

Notice the Action attribute that is set for many nodes. If you set it without assigning a value to the node, it will simply erase the previous value so that it reverts to the default.

Cycle Template

The cycle template can be used to create a visual experience similar to the one offered by the Photos Hub. Up to nine pictures can cycle on the front side of the Tile.

Anatomy of a Tile Using the Cycle Template

The cycle template offers fewer ways to customize the Tile than the other two templates since its focus is the images. The image sizes are the same as those used for the flip template:

  • Small: 159 × 159
  • Medium: 336 × 336
  • Wide: 691 × 336

A cycle template is identified by the CycleTileData class, as shown in the following sample:

The following XML can used to send remote notifications to update Tiles based on the cycle template:

Iconic Template

The iconic template is used to create Tiles that emphasize the counter. Many native applications such as Mail, Messaging, and Phone use this template. In this template, the counter is bigger and easier to see.

Anatomy of a Tile Using the Cycle Template

The iconic template features two main differences from the flip and cycle templates. The first is that full size images are not supported; instead, you can specify an icon image, which is displayed near the counter. There are just two images sizes required:

  • Small and Wide Tiles: 110 × 110
  • Medium Tile: 202 × 202

The other difference is that it’s possible to customize the background color (the only way to do this with the other templates is to use an image with the background color you prefer). If you don’t set a background color, the template will automatically use the phone’s theme.

An iconic Tile is represented by the IconicTileData template, as shown in the following sample:

The following sample is the XML representation for remote push notifications in a Tile that uses the iconic template:

Working With Multiple Tiles

The previous code, in addition to being supported in the application or in a background agent to update the main Tile, can also be used to create multiple Tiles—a feature introduced in Windows Phone 7.5. Secondary Tiles behave like the main ones: they can be updated by notifications and moved or deleted from the Start screen.

The difference is that secondary Tiles have a unique ID, which is the Tile’s deep link. The main Tile always opens the application’s main page, while secondary Tiles can open another page of the application and include one or more query string parameters to identify the context. For example, a weather application can create Tiles for the user’s favorite cities, and every Tile will redirect the user to the forecast page for the selected city.

The base class to interact with Tiles is called ShellTile, which belongs to the Microsoft.Phone.Shell namespace.

Creating a secondary Tile is simple: you call the Create() method by passing the Tile’s deep link and the Tile itself, using one of the classes we’ve seen before. The following sample shows how to create a secondary Tile using the flip template:

When the application is opened using this Tile, you’ll be able to understand the context and display the proper information using the OnNavigatedTo method and the NavigationContext class we used earlier in this series.

Note: To avoid inappropriate usage of secondary Tiles, every time you create a new Tile the application will be closed to immediately display it to the user.

Deleting a secondary Tile requires working with the ShellTile class again. It exposes a collection called ActiveTiles, which contains all the Tiles that belong to the application, including the main one. It’s sufficient to get a reference to the Tile we want to delete (using the deep link as an identifier) and call the Delete() method on it.

The previous sample deletes the Tile identified by the deep link /MainPage.xaml?id=1. Unlike when the Tile is created, the application won’t be closed.

Tip: Remember to always check that a Tile exists before removing it. Like every other Tile, in fact, users can also delete one on the main page by tapping and holding Tile and then tapping the Unpin icon.

Tiles can also be updated. Updates can be performed not only by the main application but also in the background by a background agent.

The approach is similar to the one we’ve seen for the delete operation. First we have to retrieve a reference to the Tile we want to update, and then we call the Update() method, passing the Tile object as a parameter. The following sample shows how to update a Tile that uses the flip template:

The Update() method can also be used to update the application’s main Tile. It’s always stored as the first element of the ActiveTiles collection, so it’s enough to call the Update() method on it as in the following sample:

The previous code will always work, even if the main Tile is not pinned to the Start screen. If the user decides to pin it, the Tile will already be updated with the latest notification.

Tip: You can invite users to pin the main Tile on the Start screen, but you can’t force it by code.

Interacting With the Lock Screen

Windows Phone 8 has introduced a new way for applications to interact with users, thanks to the lock screen support. There are two ways to interact with it:

  • Display notifications in the same way the Messaging and Mail apps display the number of unread messages.
  • Change the lock screen image; specifically, the application can become a lock screen provider and occasionally update the image using a background agent.

Let’s see in detail how to support both scenarios.

Notifications

In the Settings page, users can choose up to five applications that are able to display counter notifications, and only one application that is able to display text notifications.

To support both scenarios in our application, we need to manually add a new declaration in the manifest file (remember to use the View code option in the context menu since it’s not supported by the visual editor):

The first extension is used to support counter notifications, while the second one is used for text notifications. You can declare just one of them or both, according to your requirements.

If you want to support counter notifications, there’s another modification to apply to the manifest file: inside the Tokens section, you’ll find the tags that define the main Tile’s basic properties. One of them is called DeviceLockImageURI, which you need to set with the path of the image that will be used as an icon for the notifications.

The image should have the following properties:

  • The supported resolution is 38 × 38.
  • It has to be in PNG format.
  • It can contain only transparent or white pixels. No other colors are supported.

Once your application is set, you don’t have to do anything special to display lock screen notifications. In fact, they are based on Tile notifications, so you’ll be able to update both the Tile and the lock screen with just one notification.

  • If your application supports counter notifications, you need to send a Tile notification with the number stored in the Count property.
  • If your application supports text notifications, you need to send a Tile notification with the text stored in the WideBackContent property for the flip template or the WideContent1 property for an iconic template. The cycle template doesn’t support text notifications.
Lock Screen Notification with Counter and Text

Lock Screen Image

The starting point for supporting lock screen images is, again, the manifest file. The following sample is the declaration that should be added in the Extensions section:

Starting now, your application will be listed as a wallpaper provider in the Settings page. If the user chooses your application as a provider, you’ll be able to update the lock screen image, both from the foreground app and using a background agent.

The APIs allow you to check whether the application has already been set as a provider, or you can ask the user. If the application is set as a provider, you will be able to effectively change the wallpaper; otherwise you’ll get an exception.

Two classes are part of the Windows.Phone.System.UserProfile namespace: LockScreenManager can be used to detect the current provider status, and LockScreen can effectively perform operations on the lock screen.

The first step is to check if the current application is set as a provider by using the IsProvidedByCurrentApplication property of the LockScreenManager class. Otherwise, we ask for the user’s permission by calling the RequestAccessAsync() method. In return, we receive the user’s choice, which can be positive (LockScreenRequestResult.Granted) or negative (LockScreenRequestResult.Denied).

In both cases, only if the application has been set as provider can we effectively change the lock screen image using the SetImageUri() method, which requires the picture’s path as a parameter. The picture can be either part of the project (as in the previous sample where we use the ms-appx:/// prefix) or stored in the local storage (in this case, we have to use the ms-appdata:///Local/ prefix). Remote images are not directly supported; they must be downloaded before using them as a lock screen background.

The previous code can also be used for the background agent. The difference is that you’ll be able to check whether the application is set as a provider and, eventually, change the image. You won’t be able to ask to the user for permission to use your app as a provider since background agents can’t interact with the UI.

Conclusion

In this tutorial, we have seen that live apps are one of the core concepts in Windows Phone development and, to properly create a quality experience, many factors are involved, like notifications, agents, and Tiles.

The following list details what we’ve learned:

  • Push notifications are the best way to notify users of something even if the application is in the background. An app can either send toast notifications or update Tiles. We’ve seen how to create the required architecture for reach, both on the client side and the server side.
  • Push notifications offer the best approach for optimizing battery life and performance, but they support limited scenarios and require a server application to send them. For this reason, Windows Phone has introduced background agents, which we can periodically execute to send notifications or carry out general purpose operations, even when the application is not in the foreground.
  • Windows Phone offers a special background agent type called audio background agent that is used in audio playback scenarios. Applications are able to play audio even when they are not running, like the native Music + Videos Hub.
  • Alarms and reminders are a simple way to show reminders to users when the application is not running.
  • Live Tiles are one of the distinctive features of the platform. We’ve learned how to customize them by choosing between different templates and sizes.
  • We’ve seen another new feature introduced in Windows Phone 8, lock screen support: applications are now able to interact with the lock screen by displaying notifications and changing the wallpaper.

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

2015-04-16T13:50:41.000Z2015-04-16T13:50:41.000ZMatteo Pagani

An Introduction to Android's Spelling Checker Framework

$
0
0

Introduction

If you are creating a custom IME (Input Method Editor) or a language processing app, you can use Android's spelling checker framework to quickly add spell check functionality to your app without having to deal with low level tasks, such as maintaining word-lists or determining Damerau-Levenshtein distances between words.

The framework can also be used to create a custom spell checker (say for a new language or for a specific domain) that other apps can use.

This tutorial first shows you how to use the framework to interact with Android's default spell checker, and then moves on to cover the basics of developing a custom spell checker.

1. Interacting With a Spell Checker

Step 1: Create an Activity

Before we dive into the framework, let us first create an Activity that can display results of spell checks.

Create a new Java class called SpellingsClient that extends Activity. This class must also implement the SpellCheckerSession.SpellCheckerSessionListener interface to interact with Android's spell checker services. In Android Studio, you can press Alt+Insert to automatically generate empty stubs for methods of the interface.

As this Activity is going to have only one TextView in its layout, you don't need to create a layout XML for it. Override the onCreate method to initialize the TextView and pass it to the setContentView method so that it takes up the entire screen.

At this point, your class should look like this:

Step 2: Send Data to the Default Spell Checker

Let us now pass a sentence containing multiple misspelled words to Android's default spell checker. Create a method named fetchSuggestionsFor that accepts a String as a parameter.

Because the spell checker Service is a part of the Text Services API, you have to use the getSystemService method to retrieve an instance of TextServicesManager. You can then call the newSpellCheckerSession method to create a new session, which can be used to send data to the spell checker. Add the following code to the method:

Make sure the Locale you pass to newSpellCheckerSession matches the language of your input sentence.

Now that the session is ready, you can call getSentenceSuggestions to get spelling suggestions for one or more sentences.

The getSentenceSuggestions method takes two parameters. The first parameter is an array of TextInfo objects. You use the constructor of the TextInfo class to convert a String into a TextInfo object. The second parameter is an int that specifies the number of suggestions that should be generated. For this example, let us set it to 5.

Add the following code to the method:

Finally, call fetchSuggestionsFor in the onCreate method of the Activity.

Note that the getSentenceSuggestions method was introduced in API Level 16. Prior versions of the API used the, now deprecated, getSuggestions method.

Step 3: Display the Suggestions

The getSentenceSuggestions method interacts with the spell checker asynchronously. When the suggestions have been generated, the onGetSentenceSuggestions method is called.

The suggestions for each input sentence are available in a separate SentenceSuggestionsInfo object. Each SentenceSuggestionsInfo object contains multiple SuggestionsInfo objects, usually for each word of the sentence. Each SuggestionsInfo object contains the actual suggestions for a word in the form of String objects.

For this example, let us simply loop through all the suggestions and append them to a StringBuffer. Use getSuggestionsCount to determine the number of suggestions available and getSuggestionInfoAt to get a reference to a particular SuggestionInfo.

Add the following code to the onGetSentenceSuggestions method:

You can now use the TextView's setText method to render the contents of the StringBuffer. However, you cannot call the method directly, because onGetSentenceSuggestions runs on its own thread. Attempting to make changes in the user interface from a non-UI thread will lead to a runtime exception. Therefore, make sure you call the setText method from inside the runOnUiThread method.

If you run your app now, the output will look like this:

As you can see, our app is currently showing suggestions for all the words in the sentence, even for the ones with correct spelling.

To only show suggestions for misspelled words, we will have to look at the flags associated with each SuggestionsInfo object. A SuggestionsInfo object for a misspelled word has the RESULT_ATTR_LOOKS_LIKE_TYPO flag set. Therefore, we must add code to ignore SuggestionsInfo objects where this flag is not set.

Add the following code to the onGetSentenceSuggestions method before the innermost loop begins:

Run the app again to see the changed output.

2. Creating a Custom Spell Checker

Now that you know how to interact with the default spell checker, let us move on to creating a custom spell checker.

Step 1: Create a Service

Create a new Java class named SpellingService. For a class to be treated as a spell checker by the Android system, it must extend the SpellCheckerService class and override the createSession method.

Add the following code to SpellingService.java:

Step 2: Create a Session

All the custom spell checking logic resides in the Session. Create a new class named MySpellingSession that extends Session. You can create it as a subclass of SpellingService.

The Session class is an abstract class. After overriding all the abstract methods, your class should look like this:

For this tutorial, let us create a very simple spell checker that has the following features:

  • It treats the word "Peter" as a typo.
  • It returns five alternative spellings for the word "Peter".

The code to implement these features can be added to the onGetSuggestions method, because it is supposed to handle individual words (in the form of a TextInfo objects).

Extract the word using the getText method and check if it is equal to "Peter". If it is, add the appropriate suggestions to an array of String objects. If it is not, keep the array empty.

Finally, create and return a new SuggestionsInfo object that contains the array of suggestions along with the flag RESULT_ATTR_LOOKS_LIKE_TYPO. The actual code could look like this:

We are not done yet. The SpellingsClient class we created earlier passed entire sentences to the spell checker, not individual words. That means the onGetSuggestions method will never get called directly. Therefore, we need to write code that can split the sentences into words and pass them as arguments to the onGetSuggestions method. This code has to be added to the onGetSentenceSuggestionsMultiple method.

Here's what you do in the onGetSentenceSuggestionsMultiple method:

  • Loop through the array of TextInfo objects it receives as input and convert each sentence into an array of words using the split method.
  • Convert each word into a TextInfo object and pass it as an argument to the onGetSuggestions method.
  • Add the suggestions returned to an ArrayList of SuggestionsInfo objects.
  • Create and return a new array of SentenceSuggestionsInfo objects using the ArrayList of SuggestionsInfo objects.

Add the following code to the onGetSentenceSuggestionsMultiple method:

Now that the custom Session class is ready, create and return an instance of it in the service's createSession method:

Step 3: Create the Metadata for the Service

Create a new XML file called spellinginfo.xml in the res/xml folder. This file is used by the Android system to determine the name of the spell checker and the languages it supports. Let's call our spell checker My Spell Checker. Add the following code to the file:

Update your values/strings.xml so that it has service_label:

Step 4: Update the Manifest

Any Service that wants to behave as a spell checker must request the android.permission.BIND_TEXT_SERVICE permission and respond to the android.service.textservice.SpellCheckerService action. It should also contain a reference to the metadata XML we defined in the previous step. Define SpellingService by adding the following code to your AndroidManifest.xml:

Step 5: Activate the New Spell Checker

If you compile and run your app now, you will see no difference in the output of your Activity. This is because it is still using the default Android spell checker. To activate your custom spell checker, go to the Settings app and pick your spell checker in the Language and Input section.

Once activated, if you restart the app, you will see suggestions only for the word "Peter".

Conclusion

In this tutorial, you learned how to communicate with Android's spell checker services to perform spell check operations in your app. You also learned how to create your own custom spell checker. You can use this knowledge to create not only better IMEs, but also fully fledged spell checkers for languages that are currently not supported by Android by default. To know more about the TextServices API and the Spelling Checker framework, refer to the Android Developers Reference.

2015-04-17T15:30:56.000Z2015-04-17T15:30:56.000ZAshraff Hathibelagal

An Introduction to Android's Spelling Checker Framework

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

Introduction

If you are creating a custom IME (Input Method Editor) or a language processing app, you can use Android's spelling checker framework to quickly add spell check functionality to your app without having to deal with low level tasks, such as maintaining word-lists or determining Damerau-Levenshtein distances between words.

The framework can also be used to create a custom spell checker (say for a new language or for a specific domain) that other apps can use.

This tutorial first shows you how to use the framework to interact with Android's default spell checker, and then moves on to cover the basics of developing a custom spell checker.

1. Interacting With a Spell Checker

Step 1: Create an Activity

Before we dive into the framework, let us first create an Activity that can display results of spell checks.

Create a new Java class called SpellingsClient that extends Activity. This class must also implement the SpellCheckerSession.SpellCheckerSessionListener interface to interact with Android's spell checker services. In Android Studio, you can press Alt+Insert to automatically generate empty stubs for methods of the interface.

As this Activity is going to have only one TextView in its layout, you don't need to create a layout XML for it. Override the onCreate method to initialize the TextView and pass it to the setContentView method so that it takes up the entire screen.

At this point, your class should look like this:

Step 2: Send Data to the Default Spell Checker

Let us now pass a sentence containing multiple misspelled words to Android's default spell checker. Create a method named fetchSuggestionsFor that accepts a String as a parameter.

Because the spell checker Service is a part of the Text Services API, you have to use the getSystemService method to retrieve an instance of TextServicesManager. You can then call the newSpellCheckerSession method to create a new session, which can be used to send data to the spell checker. Add the following code to the method:

Make sure the Locale you pass to newSpellCheckerSession matches the language of your input sentence.

Now that the session is ready, you can call getSentenceSuggestions to get spelling suggestions for one or more sentences.

The getSentenceSuggestions method takes two parameters. The first parameter is an array of TextInfo objects. You use the constructor of the TextInfo class to convert a String into a TextInfo object. The second parameter is an int that specifies the number of suggestions that should be generated. For this example, let us set it to 5.

Add the following code to the method:

Finally, call fetchSuggestionsFor in the onCreate method of the Activity.

Note that the getSentenceSuggestions method was introduced in API Level 16. Prior versions of the API used the, now deprecated, getSuggestions method.

Step 3: Display the Suggestions

The getSentenceSuggestions method interacts with the spell checker asynchronously. When the suggestions have been generated, the onGetSentenceSuggestions method is called.

The suggestions for each input sentence are available in a separate SentenceSuggestionsInfo object. Each SentenceSuggestionsInfo object contains multiple SuggestionsInfo objects, usually for each word of the sentence. Each SuggestionsInfo object contains the actual suggestions for a word in the form of String objects.

For this example, let us simply loop through all the suggestions and append them to a StringBuffer. Use getSuggestionsCount to determine the number of suggestions available and getSuggestionInfoAt to get a reference to a particular SuggestionInfo.

Add the following code to the onGetSentenceSuggestions method:

You can now use the TextView's setText method to render the contents of the StringBuffer. However, you cannot call the method directly, because onGetSentenceSuggestions runs on its own thread. Attempting to make changes in the user interface from a non-UI thread will lead to a runtime exception. Therefore, make sure you call the setText method from inside the runOnUiThread method.

If you run your app now, the output will look like this:

As you can see, our app is currently showing suggestions for all the words in the sentence, even for the ones with correct spelling.

To only show suggestions for misspelled words, we will have to look at the flags associated with each SuggestionsInfo object. A SuggestionsInfo object for a misspelled word has the RESULT_ATTR_LOOKS_LIKE_TYPO flag set. Therefore, we must add code to ignore SuggestionsInfo objects where this flag is not set.

Add the following code to the onGetSentenceSuggestions method before the innermost loop begins:

Run the app again to see the changed output.

2. Creating a Custom Spell Checker

Now that you know how to interact with the default spell checker, let us move on to creating a custom spell checker.

Step 1: Create a Service

Create a new Java class named SpellingService. For a class to be treated as a spell checker by the Android system, it must extend the SpellCheckerService class and override the createSession method.

Add the following code to SpellingService.java:

Step 2: Create a Session

All the custom spell checking logic resides in the Session. Create a new class named MySpellingSession that extends Session. You can create it as a subclass of SpellingService.

The Session class is an abstract class. After overriding all the abstract methods, your class should look like this:

For this tutorial, let us create a very simple spell checker that has the following features:

  • It treats the word "Peter" as a typo.
  • It returns five alternative spellings for the word "Peter".

The code to implement these features can be added to the onGetSuggestions method, because it is supposed to handle individual words (in the form of a TextInfo objects).

Extract the word using the getText method and check if it is equal to "Peter". If it is, add the appropriate suggestions to an array of String objects. If it is not, keep the array empty.

Finally, create and return a new SuggestionsInfo object that contains the array of suggestions along with the flag RESULT_ATTR_LOOKS_LIKE_TYPO. The actual code could look like this:

We are not done yet. The SpellingsClient class we created earlier passed entire sentences to the spell checker, not individual words. That means the onGetSuggestions method will never get called directly. Therefore, we need to write code that can split the sentences into words and pass them as arguments to the onGetSuggestions method. This code has to be added to the onGetSentenceSuggestionsMultiple method.

Here's what you do in the onGetSentenceSuggestionsMultiple method:

  • Loop through the array of TextInfo objects it receives as input and convert each sentence into an array of words using the split method.
  • Convert each word into a TextInfo object and pass it as an argument to the onGetSuggestions method.
  • Add the suggestions returned to an ArrayList of SuggestionsInfo objects.
  • Create and return a new array of SentenceSuggestionsInfo objects using the ArrayList of SuggestionsInfo objects.

Add the following code to the onGetSentenceSuggestionsMultiple method:

Now that the custom Session class is ready, create and return an instance of it in the service's createSession method:

Step 3: Create the Metadata for the Service

Create a new XML file called spellinginfo.xml in the res/xml folder. This file is used by the Android system to determine the name of the spell checker and the languages it supports. Let's call our spell checker My Spell Checker. Add the following code to the file:

Update your values/strings.xml so that it has service_label:

Step 4: Update the Manifest

Any Service that wants to behave as a spell checker must request the android.permission.BIND_TEXT_SERVICE permission and respond to the android.service.textservice.SpellCheckerService action. It should also contain a reference to the metadata XML we defined in the previous step. Define SpellingService by adding the following code to your AndroidManifest.xml:

Step 5: Activate the New Spell Checker

If you compile and run your app now, you will see no difference in the output of your Activity. This is because it is still using the default Android spell checker. To activate your custom spell checker, go to the Settings app and pick your spell checker in the Language and Input section.

Once activated, if you restart the app, you will see suggestions only for the word "Peter".

Conclusion

In this tutorial, you learned how to communicate with Android's spell checker services to perform spell check operations in your app. You also learned how to create your own custom spell checker. You can use this knowledge to create not only better IMEs, but also fully fledged spell checkers for languages that are currently not supported by Android by default. To know more about the TextServices API and the Spelling Checker framework, refer to the Android Developers Reference.

2015-04-17T15:30:56.000Z2015-04-17T15:30:56.000ZAshraff Hathibelagal

Creating an Android Wear Watch Face

$
0
0

One of the features that makes Android so special is the ability to customize every aspect of the user experience. When Android Wear first launched at Google I/O 2014, many developers and users found out that this wasn't exactly true for smart watches, as the official API for creating watch faces was noticeably missing. Given that the ability to make custom watch faces was one of the key wants from users, it's not surprising that developers discovered a way to create their own watch faces with an undocumented hack in Android Wear.

Luckily, Google quickly let everyone know that an official API was on its way and in December of 2014 that API was finally released to the development community. In this article, you're going to learn about the official Watch Faces API for Android Wear and implement a simple digital watch face that you will be able to expand on for your own needs. Implementing watch faces can be a bit verbose, but you can find the sample application for this article on GitHub.

1. Setting Up Your IDE

The first thing you're going to need to do to make your own watch face is get your project set up in Android Studio. When creating your project, select Phone and Tablet with a Minimum SDK of API 18 as Android 4.3 is the lowest version of the operating system to support bundled Android Wear applications. You will also need to check the Wear box with a Minimum SDK of API 21 selected. You can see an example of what your Target Android Devices screen should look like.

When you get to the two Add an Activity screens, select Add No Activity for both screens.

Once you click Finish, your project environment should build and have a module for mobile and another one for wear.

2. Building the Wear Watch Service

Android Wear implements watch faces through the use of WatchFaceService. In this article, you're going create an extension of the CanvasWatchFaceService class, which is an implementation of WatchFaceService that also provides a Canvas for drawing out your watch face. Start by creating a new Java class under the wear module in Android Studio that extends CanvasWatchFaceService.

Once you have your class, you're going to need to create an inner class, WatchFaceEngine in the source files of this article, that extends Engine. This is the watch face engine that handles system events, such as the screen turning off or going into ambient mode.

When your stub code for WatchFaceEngine is in, go back to the outer class and override the onCreateEngine method to return your new inner class. This will associate your watch face service with the code that will drive the display.

Once you have the bare bones service put together, you can move on to the general housekeeping tasks of updating your AndroidManifest files so that your service will be discoverable by Android Wear. Keep in mind that your current code won't do anything yet. We will come back to this class and flesh out the engine after doing some project housekeeping.

3. Updating the AndroidManifest Files

Open the AndroidManifest.xml file in the wear module. Near the top you should already see a line that says:

Below that line, we need to add in the two required permissions for a watch face. These requirement are:

Once your permissions are set, you will need to add a node for your service in the application node with permission to BIND_WALLPAPER, a few sets of meta-data containing reference images of your watch face for the selection screen (in this example we're just using the launcher icon), and an intent-filter to let the system know that your service is meant for displaying a watch face.

Once your wear manifest is complete, you will need to open the AndroidManifest.xml file in the mobile module and add in the two permissions we used in the wear module for PROVIDE_BACKGROUND and WAKE_LOCK, because Android Wear requires that both the wear and mobile modules request the same permissions for the wear APK to be installed on a user's watch. Once both manifest files are filled in, you can return to CustomWatchFaceService.java to start implementing the engine.

4. Start Your Engine

The Engine object associated with your service is what drives your watch face. It handles timers, displaying your user interface, moving in and out of ambient mode, and getting information about the physical watch display. In short, this is where the magic happens.

Step 1: Defining Necessary Values and Variables

The first thing you're going to want to do is implement a set of member variables in your engine to keep track of device states, timer intervals, and attributes for your display.

As you can see, we define the TypeFace that we will use for our digital watch text as well as the watch face background color and text color. The Time object is used for, you guessed it, keeping track of the current device time. mUpdateRateMs is used to control a timer that we will need to implement to update our watch face every second (hence the 1000 milliseconds value for mUpdateRateMs), because the standard WatchFaceService only keeps track of time in one minute increments. mXOffset and mYOffset are defined once the engine knows the physical shape of the watch so that our watch face can be drawn without being too close to the top or left of the screen, or being cut off by a rounded corner. The three boolean values are used to keep track of different device and application states.

The next object you will need to define is a broadcast receiver that handles the situation where a user may be traveling and change time zones. This receiver simply clears out the saved time zone and resets the display time.

After your receiver is defined, the final object you will need to create at the top of your engine is a Handler to takes care of updating your watch face every second. This is necessary because of the limitations of WatchFaceService discussed above. If your own watch face only needs to be updated every minute, then you can safely ignore this section.

The implementation of the Handler is pretty straightforward. It first checks the message ID. If matches MSG_UPDATE_TIME_ID, it continues to invalidate the current view for redrawing. After the view has been invalidated, the Handler checks to see if the screen is visible and not in ambient mode. If it is visible, it sends a repeat request a second later. The reason we're only repeating the action in the Handler when the watch face is visible and not in ambient mode is that it can be a little battery intensive to keep updating every second. If the user isn't looking at the screen, we simply fall back on the WatchFaceService implementation that updates every minute.

Step 2: Initializing the Engine

Now that your variables and objects are declared, it's time to start initializing the watch face. Engine has an onCreate method that should be used for creating objects and other tasks that can take a significant amount of time and battery. You will also want to set a few flags for the WatchFaceStyle here to control how the system interacts with the user when your watch face is active.

For the sample app, you'll use setWatchFaceStyle to set the background of your notification cards to briefly show if the card type is set as interruptive. You'll also set the peek mode so that notification cards only take up as much room as necessary.

Finally, you'll want to tell the system to not show the default time since you will be displaying it yourself. While these are only a few of the options available, you can find even more information in the official documentation for the WatchFaceStyle.Builder object.

After your WatchFaceStyle has been set, you can initialize mDisplayTime as a new Time object.

initBackground and initDisplayText allocate the two Paint objects that you defined at the top of the engine. The background and text then have their color set and the text has its typeface and font size set, while also turning on anti-aliasing.

Step 3: Handling Device State

Next, you need to implement various methods from the Engine class that are triggered by changes to the device state. We'll start by going over the onVisibilityChanged method, which is called when the user hides or shows the watch face.

When this method is called, it checks to see whether the watch face is visible or not. If the watch face is visible, it looks to see if the BroadcastReceiver that you defined at the top of the Engine is registered. If it isn't, the method creates an IntentFilter for the ACTION_TIMEZONE_CHANGED action and registers the BroadcastReceiver to listen for it.

If the watch face is not visible, this method will check to see if the BroadcastReceiver can be unregistered. Once the BroadcastReceiver has been handled, updateTimer is called to trigger invalidating the watch face and redraw the watch face. updateTimer stops any Handler actions that are pending and checks to see if another should be sent.

Step 4: Cooperating With the Wearable Hardware

When your service is associated with Android Wear, onApplyWindowInsets is called. This is used to determine if the device your watch face is running on is rounded or squared. This lets you change your watch face to match up with the hardware.

When this method is called in the sample application, this method simply checks the device shape and changes the x offset used for drawing the watch face to make sure your watch face is visible on the device.

The next method that you will need to override is onPropertiesChanged. This method is called when the hardware properties for the Wear device are determined, for example, if the device supports burn-in protection or low bit ambient mode.

In this method, you check if those attributes apply to the device running your watch face and save them in a member variable defined at the top of your Engine.

Step 5: Conserving Battery in Ambient and Muted Modes

After you handle the initial device states, you will want to implement onAmbientModeChanged and onInterruptionFilterChanged. As the name implies, onAmbientModeChanged is called when the device moves in or out of ambient mode.

If the device is in ambient mode, you will want to change the color of your watch face to be black and white to be mindful of the user's battery. When the device is returning from ambient mode, you can reset your watch face's colors. You will also want to be mindful of anti-aliasing for devices that request low bit ambient support. After all of the flag variables are set, you can cause the watch face to invalidate and redraw, and then check if the one second timer should start.


onInterruptionFilterChanged is called when the user manually changes the interruption settings on their wearable. When this happens, you will need to check if the device is muted and then alter the user interface accordingly. In this situation, you will change the transparency of your watch face, set your Handler to only update every minute if the device is muted, and then redraw your watch face.

When your device is in ambient mode, the Handler timer will be disabled. Your watch face can still update with the current time every minute through using the built-in onTimeTick method to invalidate the Canvas.

Step 6: Drawing the Watch Face

Once all of your contingencies are covered, it's time to finally draw out your watch face. CanvasWatchFaceService uses a standard Canvas object, so you will need to add onDraw to your Engine and manually draw out your watch face.

In this tutorial we're simply going to draw a text representation of the time, though you could change your onDraw to easily support an analog watch face. In this method, you will want to verify that you are displaying the correct time by updating your Time object and then you can start applying your watch face.

drawBackground applies a solid color to the background of the Wear device.

drawTimeText, however, creates the time text that will be displayed with the help of a couple helper methods and then applies it to the canvas at the x and y offset points that you defined in onApplyWindowInsets.

Conclusion

Once you've implemented the methods for drawing your watch face, you should be all set with the basic knowledge needed to go out and make your own watch faces. The nice thing about Android Wear watch faces is that this is just scratching the surface of what's possible.

You can add companion configuration activities on the watch or on the phone, replace the Canvas based watch face with an OpenGL implementation, or derive your own class from WatchFaceService to meet your needs.

Add to it that you can access other APIs or information from the user's phone and the possibilities seem endless. Get creative with your watch faces and enjoy.

2015-04-20T16:15:50.000Z2015-04-20T16:15:50.000ZPaul Trebilcox-Ruiz

Creating an Android Wear Watch Face

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

One of the features that makes Android so special is the ability to customize every aspect of the user experience. When Android Wear first launched at Google I/O 2014, many developers and users found out that this wasn't exactly true for smart watches, as the official API for creating watch faces was noticeably missing. Given that the ability to make custom watch faces was one of the key wants from users, it's not surprising that developers discovered a way to create their own watch faces with an undocumented hack in Android Wear.

Luckily, Google quickly let everyone know that an official API was on its way and in December of 2014 that API was finally released to the development community. In this article, you're going to learn about the official Watch Faces API for Android Wear and implement a simple digital watch face that you will be able to expand on for your own needs. Implementing watch faces can be a bit verbose, but you can find the sample application for this article on GitHub.

1. Setting Up Your IDE

The first thing you're going to need to do to make your own watch face is get your project set up in Android Studio. When creating your project, select Phone and Tablet with a Minimum SDK of API 18 as Android 4.3 is the lowest version of the operating system to support bundled Android Wear applications. You will also need to check the Wear box with a Minimum SDK of API 21 selected. You can see an example of what your Target Android Devices screen should look like.

When you get to the two Add an Activity screens, select Add No Activity for both screens.

Once you click Finish, your project environment should build and have a module for mobile and another one for wear.

2. Building the Wear Watch Service

Android Wear implements watch faces through the use of WatchFaceService. In this article, you're going create an extension of the CanvasWatchFaceService class, which is an implementation of WatchFaceService that also provides a Canvas for drawing out your watch face. Start by creating a new Java class under the wear module in Android Studio that extends CanvasWatchFaceService.

Once you have your class, you're going to need to create an inner class, WatchFaceEngine in the source files of this article, that extends Engine. This is the watch face engine that handles system events, such as the screen turning off or going into ambient mode.

When your stub code for WatchFaceEngine is in, go back to the outer class and override the onCreateEngine method to return your new inner class. This will associate your watch face service with the code that will drive the display.

Once you have the bare bones service put together, you can move on to the general housekeeping tasks of updating your AndroidManifest files so that your service will be discoverable by Android Wear. Keep in mind that your current code won't do anything yet. We will come back to this class and flesh out the engine after doing some project housekeeping.

3. Updating the AndroidManifest Files

Open the AndroidManifest.xml file in the wear module. Near the top you should already see a line that says:

Below that line, we need to add in the two required permissions for a watch face. These requirement are:

Once your permissions are set, you will need to add a node for your service in the application node with permission to BIND_WALLPAPER, a few sets of meta-data containing reference images of your watch face for the selection screen (in this example we're just using the launcher icon), and an intent-filter to let the system know that your service is meant for displaying a watch face.

Once your wear manifest is complete, you will need to open the AndroidManifest.xml file in the mobile module and add in the two permissions we used in the wear module for PROVIDE_BACKGROUND and WAKE_LOCK, because Android Wear requires that both the wear and mobile modules request the same permissions for the wear APK to be installed on a user's watch. Once both manifest files are filled in, you can return to CustomWatchFaceService.java to start implementing the engine.

4. Start Your Engine

The Engine object associated with your service is what drives your watch face. It handles timers, displaying your user interface, moving in and out of ambient mode, and getting information about the physical watch display. In short, this is where the magic happens.

Step 1: Defining Necessary Values and Variables

The first thing you're going to want to do is implement a set of member variables in your engine to keep track of device states, timer intervals, and attributes for your display.

As you can see, we define the TypeFace that we will use for our digital watch text as well as the watch face background color and text color. The Time object is used for, you guessed it, keeping track of the current device time. mUpdateRateMs is used to control a timer that we will need to implement to update our watch face every second (hence the 1000 milliseconds value for mUpdateRateMs), because the standard WatchFaceService only keeps track of time in one minute increments. mXOffset and mYOffset are defined once the engine knows the physical shape of the watch so that our watch face can be drawn without being too close to the top or left of the screen, or being cut off by a rounded corner. The three boolean values are used to keep track of different device and application states.

The next object you will need to define is a broadcast receiver that handles the situation where a user may be traveling and change time zones. This receiver simply clears out the saved time zone and resets the display time.

After your receiver is defined, the final object you will need to create at the top of your engine is a Handler to takes care of updating your watch face every second. This is necessary because of the limitations of WatchFaceService discussed above. If your own watch face only needs to be updated every minute, then you can safely ignore this section.

The implementation of the Handler is pretty straightforward. It first checks the message ID. If matches MSG_UPDATE_TIME_ID, it continues to invalidate the current view for redrawing. After the view has been invalidated, the Handler checks to see if the screen is visible and not in ambient mode. If it is visible, it sends a repeat request a second later. The reason we're only repeating the action in the Handler when the watch face is visible and not in ambient mode is that it can be a little battery intensive to keep updating every second. If the user isn't looking at the screen, we simply fall back on the WatchFaceService implementation that updates every minute.

Step 2: Initializing the Engine

Now that your variables and objects are declared, it's time to start initializing the watch face. Engine has an onCreate method that should be used for creating objects and other tasks that can take a significant amount of time and battery. You will also want to set a few flags for the WatchFaceStyle here to control how the system interacts with the user when your watch face is active.

For the sample app, you'll use setWatchFaceStyle to set the background of your notification cards to briefly show if the card type is set as interruptive. You'll also set the peek mode so that notification cards only take up as much room as necessary.

Finally, you'll want to tell the system to not show the default time since you will be displaying it yourself. While these are only a few of the options available, you can find even more information in the official documentation for the WatchFaceStyle.Builder object.

After your WatchFaceStyle has been set, you can initialize mDisplayTime as a new Time object.

initBackground and initDisplayText allocate the two Paint objects that you defined at the top of the engine. The background and text then have their color set and the text has its typeface and font size set, while also turning on anti-aliasing.

Step 3: Handling Device State

Next, you need to implement various methods from the Engine class that are triggered by changes to the device state. We'll start by going over the onVisibilityChanged method, which is called when the user hides or shows the watch face.

When this method is called, it checks to see whether the watch face is visible or not. If the watch face is visible, it looks to see if the BroadcastReceiver that you defined at the top of the Engine is registered. If it isn't, the method creates an IntentFilter for the ACTION_TIMEZONE_CHANGED action and registers the BroadcastReceiver to listen for it.

If the watch face is not visible, this method will check to see if the BroadcastReceiver can be unregistered. Once the BroadcastReceiver has been handled, updateTimer is called to trigger invalidating the watch face and redraw the watch face. updateTimer stops any Handler actions that are pending and checks to see if another should be sent.

Step 4: Cooperating With the Wearable Hardware

When your service is associated with Android Wear, onApplyWindowInsets is called. This is used to determine if the device your watch face is running on is rounded or squared. This lets you change your watch face to match up with the hardware.

When this method is called in the sample application, this method simply checks the device shape and changes the x offset used for drawing the watch face to make sure your watch face is visible on the device.

The next method that you will need to override is onPropertiesChanged. This method is called when the hardware properties for the Wear device are determined, for example, if the device supports burn-in protection or low bit ambient mode.

In this method, you check if those attributes apply to the device running your watch face and save them in a member variable defined at the top of your Engine.

Step 5: Conserving Battery in Ambient and Muted Modes

After you handle the initial device states, you will want to implement onAmbientModeChanged and onInterruptionFilterChanged. As the name implies, onAmbientModeChanged is called when the device moves in or out of ambient mode.

If the device is in ambient mode, you will want to change the color of your watch face to be black and white to be mindful of the user's battery. When the device is returning from ambient mode, you can reset your watch face's colors. You will also want to be mindful of anti-aliasing for devices that request low bit ambient support. After all of the flag variables are set, you can cause the watch face to invalidate and redraw, and then check if the one second timer should start.


onInterruptionFilterChanged is called when the user manually changes the interruption settings on their wearable. When this happens, you will need to check if the device is muted and then alter the user interface accordingly. In this situation, you will change the transparency of your watch face, set your Handler to only update every minute if the device is muted, and then redraw your watch face.

When your device is in ambient mode, the Handler timer will be disabled. Your watch face can still update with the current time every minute through using the built-in onTimeTick method to invalidate the Canvas.

Step 6: Drawing the Watch Face

Once all of your contingencies are covered, it's time to finally draw out your watch face. CanvasWatchFaceService uses a standard Canvas object, so you will need to add onDraw to your Engine and manually draw out your watch face.

In this tutorial we're simply going to draw a text representation of the time, though you could change your onDraw to easily support an analog watch face. In this method, you will want to verify that you are displaying the correct time by updating your Time object and then you can start applying your watch face.

drawBackground applies a solid color to the background of the Wear device.

drawTimeText, however, creates the time text that will be displayed with the help of a couple helper methods and then applies it to the canvas at the x and y offset points that you defined in onApplyWindowInsets.

Conclusion

Once you've implemented the methods for drawing your watch face, you should be all set with the basic knowledge needed to go out and make your own watch faces. The nice thing about Android Wear watch faces is that this is just scratching the surface of what's possible.

You can add companion configuration activities on the watch or on the phone, replace the Canvas based watch face with an OpenGL implementation, or derive your own class from WatchFaceService to meet your needs.

Add to it that you can access other APIs or information from the user's phone and the possibilities seem endless. Get creative with your watch faces and enjoy.

2015-04-20T16:15:50.000Z2015-04-20T16:15:50.000ZPaul Trebilcox-Ruiz

Design Patterns: Dependency Injection

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

Even though dependency injection is a topic that is rarely taught to beginners, it is a design pattern that deserves more attention. Many developers avoid dependency injection, because they don't know what it means or because they think that they don't need it.

In this article, I'm going to try to convince you of the value of dependency injection. To do this, I will introduce you to dependency injection by showing you how simple it is in its simplest form.

1. What Is Dependency Injection?

Much has been written about dependency injection and there are a bunch of tools and libraries that aim to simplify dependency injection. There is one quote, however, that captures the confusion many people have around dependency injection.

"Dependency Injection" is a 25-dollar term for a 5-cent concept. - James Shore

Once you grasp the idea that underlies dependency injection, you will also understand the above quote. Let's start with an example to illustrate the concept.

An iOS application has many dependencies and your application may rely on dependencies you're not even aware of, that is, you don't consider them dependencies. The following code snippet shows the implementation of a UIViewController subclass named ViewController. The implementation includes a method named saveList:. Can you spot the dependency?

The most commonly overlooked dependencies are the ones that we rely on the most. In the saveList: method, we store an array in the user defaults database, accessible through the NSUserDefaults class. We access the shared defaults object by invoking the standardUserDefaults method. If you're somewhat familiar with iOS or OS X development, then you're likely to be familiar with the NSUserDefaults class.

Storing data in the user defaults database is fast, easy, and reliable. Thanks to the standardUserDefaults method, we have access to the user defaults database from anywhere in the project. The method returns a singleton that we can use whenever and wherever we want. Life can be beautiful.

Singleton? Whenever and wherever? Do you smell something? Not only do I smell a dependency, I also smell a bad practice. In this article, I don't want to open up a can of worms by discussing the use and misuse of singletons, but it is important to understand that singletons should be used sparingly.

Most of us have become so used to the user defaults database that we don't see it as a dependency. But it certainly is one. The same is true for the notification center, which we commonly access through the singleton accessible through the defaultCenter method. Take a look at the following example for clarification.

The above scenario is very common. We add the view controller as an observer for notifications with name UIApplicationWillEnterForegroundNotification and remove it as an observer in the dealloc method of the class. This adds another dependency to the ViewController class, a dependency that is often overlooked—or ignored.

The question you may be asking yourself is "What is the problem?" or better "Is there a problem?" Let's start with the first question.

What Is the Problem?

Based on the above examples, it may seem as if there is no problem. That isn't entirely true though. The view controller depends on the shared defaults object and the default notification center to do its work.

Is that a problem? Almost every object relies on other objects to do its work. The issue is that the dependencies are implicit. A developer new to the project doesn't know the view controller relies on these dependencies by inspecting the class interface.

Testing the ViewController class will also prove to be tricky since we don't control the NSUserDefaults and NSNotificationCenter classes. Let's look at some solutions to this problem. In other words, let's see how dependency injection can help us solve this problem.

2. Injecting Dependencies

As I mentioned in the introduction, dependency injection is a very simple concept. James Shore has written a great article about the simplicity of dependency injection. There is one other quote from James Shore about what dependency injection is at its very core.

Dependency injection means giving an object its instance variables. Really. That's it. - James Shore

There are a number of ways to accomplish this, but it's important to first understand what the above quote means. Let's see how we can apply this to the ViewController class.

Instead of accessing the default notification center in the init method through the defaultCenter class method, we create a property for the notification center in the ViewController class. This is what the updated interface of the ViewController class looks like after this addition.

This also means that we need to do a bit of extra work when we initialize an instance of the ViewController class. As James writes, we hand the ViewController instance its instance variables. That is how simple dependency injection is. It's a fancy name for a straightforward concept.

As a result of this change, the implementation of the ViewController class changes. This is what the init and dealloc methods look like when injecting the default notification center.

Note that we don't use self in the dealloc method. This is considered a bad practice since it may lead to unexpected results.

There is one problem. Can you spot it? In the initializer of the ViewController class, we access the notificationCenter property to add the view controller as an observer. During initialization, however, the notificationCenter property hasn't been set yet. We can solve this problem by passing the dependency as a parameter of the initializer. This is what that looks like.

To make this work, we also need to update the interface of the ViewController class. We omit the notificationCenter property and add a method declaration for the initializer we created.

In the implementation file, we create a class extension in which we declare the notificationCenter property. By doing so, the notificationCenter property is private to the ViewController class and can only be set by invoking the new initializer. This is another best practice to keep in mind, only expose properties that need to be public.

To instantiate an instance of the ViewController class, we rely on the initializer we created earlier.

3. Benefits

What have we accomplished by explicitly injecting the notification center object as a dependency?

Clarity

The interface of the ViewController class unequivocally shows that the class relies or depends on the NSNotificationCenter class. If you're new to iOS or OS X development, this may seem like a small win for the complexity we added. However, as your projects become more complex, you will learn to appreciate every bit of clarity you can add to a project. Explicitly declaring dependencies will help you with this.

Modularity

When you start using dependency injection, your code will become much more modular. Even though we injected a specific class into the ViewController class, it is possible to inject an object that conforms to a specific protocol. If you adopt this approach, it will become much easier to replace one implementation with another.

In the above interface of the ViewController class, we declare another dependency. The dependency is an object that conforms to the MyProtocol protocol. This is where the true power of dependency injection becomes apparent. The ViewController class doesn't care about the type of someObject, it only asks that it adopts the MyProtocol protocol. This makes for highly modular, flexible, and testable code.

Testing

Even though testing isn't as widespread among iOS and OS X developers as it is in other communities, testing is an key topic that gains in importance and popularity. By adopting dependency injection, you will make your code much easier to test. How would you test the following initializer? That's going to be tricky. Right?

The second initializer, however, makes this task much easier. Take a look at the initializer and the test that goes with it.

The above test makes use of the OCMock library, an excellent mocking library for Objective-C. Instead of passing in an instance of the NSNotificationCenter class, we pass in a mock object and verify whether the methods that need to be invoked in the initializer are indeed invoked.

There are several approaches to test notification handling and this is—by far—the easiest I've come across. It adds a bit of overhead by injecting the notification center object as a dependency, but the benefit outweighs the added complexity in my opinion.

4. Third Party Solutions

I hope I've convinced you that dependency injection is a simple concept with a simple solution. There are, however, a number of popular frameworks and libraries that aim to make dependency injection more powerful and easier to manage for complex projects. The two most popular libraries are Typhoon and Objection.

If you're new to dependency injection, then I strongly recommend to start using the techniques outlined in this tutorial. You first need to properly understand the concept before relying on a third party solution, such as Typhoon or Objection.

Conclusion

The goal of this article was to make dependency injection easier to understand for people who are new to programming and unfamiliar with the concept. I hope I have convinced you of the value of dependency injection and the simplicity of the underlying idea.

There are a number of excellent resources about dependency injection. James Shore's article about dependency injection is a must-read for every developer. Graham Lee also wrote a great article aimed at iOS and OS X developers.

2015-04-22T20:15:19.000Z2015-04-22T20:15:19.000ZBart Jacobs

Windows Phone 8 Succinctly: Localization, Windows Phone Store & In-App Purchases

$
0
0

When we talk about mobile applications, development isn't the only aspect we need to consider. If we want to be successful, we also have to distribute and promote our application. In this tutorial, we're going to discuss localization, the Windows Phone store, and in-app purchases.

Trial Apps

One of the distinctive features of Windows Phone applications is that they support a trial mode, which enables them to be downloaded from the Windows Phone Store as a trial with limited features. Once users decide to buy the full application, they don’t have to download it from scratch; the Store will simply download an updated certificate, which will unlock all the previously blocked features.

From the developer point of view, managing a trial is simple. The Windows.ApplicationModel.Store namespace contains a class called LicenseInformation, which offers a property called IsTrial. If its value is true, it means that the application has been installed in trial mode, so we have to lock the features we don’t want enabled; otherwise, the user has purchased it, so all features can be made available.

It’s up to you to choose the best trial experience for your application. For example, you can disable some features, limit the number of times the applications can be executed, or in a game, choose which levels to unlock.

Localization

One of the best ways to increase the sales and number of downloads of an application is to support multiple languages. The default Windows Phone 8 template in Visual Studio already supports localization by including a folder called Resources. It contains all resource files, which are simple XML files with a special .resx extension.

Resource files are simply a collection of values (the translated text) associated with a specific key which is used in the application to refer to that text. According to the user’s language, the application will automatically use the proper resource file.

The standard template creates a file called AppResources.resx inside the Resources folder, which refers to the standard language (usually English). 

Supporting a new language is easy. Just right-click your project in the Solution Explorer and choose Properties. The supported cultures box will display all the available languages. When you add new languages by selecting them in the list, Visual Studio will automatically create a new AppResources file named AppResources.xx-yy.resx in the Resources folder, where xx-yy is the culture code of the selected language (for example, if you’ve added Italian, it will create a file named AppResources.it-IT.resx).

Visual Studio offers a useful visual editor for working with resource files. It displays all the values inside a table, where you can easily define a key, its value, and an optional comment. To access it, simply double-click on a resource file in the Resources folder.

In addition to offering a standard resource file, the Windows Phone template also includes a class called LocalizedStrings, which acts as a wrapper between the localization file and the XAML. You can find it defined as a global resource in the App.xaml file:

Thanks to this wrapper, you’ll be able to access resources directly in XAML. You don’t have to add it directly in the XAML every time you need to display text in the user interface; instead you’ll add in the resource files and then connect them to your XAML with the following syntax:

Thanks to the LocalizedStrings class, we can access every value in the resource file simply by using the LocalizedResources.MyKey syntax, where MyKey is the key that identifies the text that you want to display.

If you want to access the resource string directly from code, you’ll have to use the AppResources singleton class, as shown in the following sample:

The Multilingual App Toolkit

Microsoft has created a useful Visual Studio extension called Multilingual App Toolkit, which can be downloaded from the Windows Dev Center. The tool doesn’t change how localization works; it will always be based on resource files, which are accessed by the application using the LocalizedString class.

The following list details some of the main benefits of the Multilingual App Toolkit:

  • One of the most time-consuming aspects of working with localization is manually copying all the new values you have added in the basic language to all other resource files. The Multilingual App Toolkit will do this for you. During the build process, it will copy all the new keys added to the AppResources.resx file to all the other resource files.
  • It offers a better visual interface for managing translations. You’ll be able to immediately identify the new keys to translate and set a different translation status.
  • It supports Bing services to automatically translate sentences. Obviously, you can’t completely rely on automatic translations, but they can be a good start for your localization process.
  • It’s able to automatically generate pseudo language, which is a way to immediately identify untranslated resources and have a better idea of how much space text occupies in the UI.

After you’ve installed the toolkit, you’ll have to enable it for your project in the Tools menu of Visual Studio by selecting the Enable multilingual app toolkit option. After enabling it, Visual Studio will work with .xlf files instead of .resx files (except for the main language). During the compilation process, the toolkit will generate all the required .resx files for you.

To access the toolkit visual interface, just double-click an .xlf file and you’ll see the complete list of resources. An icon will notify you of the status of each resource. If the resource has not yet been translated, a red circle is displayed. If the resource has been translated but requires revision, a yellow circle is displayed. If the translation has been approved, a green circle is displayed.

Multilingual App Toolkit

Forcing a Language

Windows Phone will automatically pick the resource file that matches the phone’s language. If an appropriate resource file is missing (because the phone’s language is not supported by your application), the default will be used.

You can change this behavior, for example, if you want to give users the option to choose the language they prefer, regardless of the phone’s language. To do this, you’ll need to set a different culture code when the App class (declared in the App.xaml.cs file) is created:

After you’ve defined a CultureInfo object by passing the culture code as a parameter, you can assign it to two different properties of the Thread.CurrentThread object:

  • CurrentCulture is the application’s culture, which is used to define features like date and time formats, currency, etc.
  • CurrentUICulture is the user interface culture, which is used to understand which resource file to pick.

This approach is also required if you want to use the pseudo language generated by the Multilingual App Toolkit during the testing process. Since pseudo language is not an official language supported by the platform, you’ll have to force it using the qps-ploc culture code, as shown in the following sample:

Using pseudo language is a great way to identify text that has yet to be translated and test whether your application’s layout is able to manage long text. What typically happens when developing an application is that you test it with only a couple languages, forgetting that a word that looks very short in English, for example, can be very long when it’s translated to German.

The Store Experience

As mentioned in the first article, the Windows Phone Store is the only way to distribute applications to your users unless you’re pursuing enterprise distribution. You’ll need a paid developer account, which can be purchased from the Windows Dev Center. The fee is $19 per year, unless you’re a student subscribed to the DreamSpark program, in which case access is free. A similar benefit is granted to MSDN subscribers: in the benefits page, you can get a token that allows you to register for free.

Other than the annual fee, Microsoft applies a revenue-sharing approach: 30% of the application’s price is kept by Microsoft, while the other 70% is given to the developer. Of course, this sharing doesn’t apply if the app is free.

Once your developer account has been activated and your application is ready, you can submit it to the portal at dev.windowsphone.com. During the process, you’ll have to define the application marketing features, like price, metadata, and distribution type. After that, the submission is completed, and the certification process starts. Applications are not automatically published to the Store; first they need to pass a certification process that validates the application both from a technical and content point of view.

The technical tests make sure that the application offers a good experience to users: it doesn’t crash, it’s fast and responsive, and the user interface is not confusing.

The manual tests check the content of the application. Some types of content like pornography, excessive violence, etc., are not allowed and will lead to a certification failure.

When you start the submission process, you’ll see a list of steps to follow to complete the process. Let’s briefly look at each step.

Step 1: App Info

The first step of the publishing process is used to set some basic information, like the app’s category, price tier, and market distribution. Your application will automatically be distributed in all the supported countries at the price you’ve chosen. The price will be automatically converted into each country’s currency. 

In this step, you can choose to automatically exclude countries like China, where the content policies are stricter. The certification process also offers an optional Market selection and custom pricing step, which offers deeper customization: you can choose to distribute the applications only in specific countries and customize the price for each country.

The other important option to set during this step is the distribution channel. There are three ways to distribute a Windows Phone application:

  • The public store: The app can be discovered and downloaded by any user.
  • Hidden: The app is still available in the public store, but it can’t be discovered by users. The only way to find it is by using the direct link that is generated when the app is published.
  • Beta: The application can’t be discovered by users, and moreover, only authorized users will be allowed to download it. Users are authorized with the Microsoft account they registered the phone with. You’ll be able to include up to 10,000 users during the submission process. This distribution channel was created to support beta testing; in this scenario, however, the application won’t actually be tested, but will be available to the selected users within two hours of submitting the app. A beta application automatically expires 90 days after it’s been submitted for the first time, regardless of later updates.

Step 2: Upload and Describe Your XAP

The second step requires more time to complete, since you’ll have to provide all the application information that will be displayed in the Windows Phone Store.

The first step is to upload the XAP file. The XAP is the package produced by Visual Studio when you compile your project, and it contains all the required files for the application to run. You’ll find it inside the bin folder of your Visual Studio project. Remember to always compile the application in release mode; otherwise it won’t be accepted.

Once you’ve uploaded the XAP, the portal will automatically display a recap of the application’s features, like the supported resolutions, the required capabilities, and so on. You’ll also have to set the version number of the application you’re uploading.

The portal will also automatically detect the languages you support, which will be displayed in a drop-down menu called Language details. You’ll have to set the application’s metadata (title, description, and keywords) for every supported language. This information will be displayed in the Store when the user opens your application’s page.

Information about the App Displayed in the Store

You will also need to upload at least one screenshot (eight are allowed) for every language and supported resolution, plus the application icon. They will be displayed in the screenshots section of the Store. To take screenshots, you can use one of the tools available in the emulator.

Once you’ve completed all the required steps, the portal will show you a recap of the submission for your confirmation.

Managing the Application’s Life Cycle

Once your application has been certified, you’ll have access to many reports that will help you understand how well your application is performing. There are download reports, sales reports, and crash reports.

If the application doesn’t pass the certification process, you’ll find in your dashboard a PDF file containing the full report. It will tell you in detail what went wrong and what you should do to fix the identified problems.

In the end, of course, you can also update your application. In this case you’ll simply have to repeat all the submission steps, although all the fields will already be filled with the old information and metadata. The process is also the same if you just want to change information like the price, description, and screenshots. The submission only has to be certified if you’ve changed any information that needs to be validated. If you only change the price, the update is immediately published.

In-App Purchases

A different way to make money with Windows Phone apps is to support in-app purchases. In addition to buying the app from the Store, users can also make purchases within the application itself.

In-app purchases have always been allowed, but Windows Phone 8 has introduced specific APIs and Microsoft backend support. Previously, the developer was in charge of creating the server infrastructure, managing payments, and connecting the client.

Now, you can simply rely on the Store infrastructure. Users will pay using the same credit card they used to purchase apps or music from the Store, and the portal will allow you to create one or more products to buy within the application. Also in this case, the revenue-sharing approach will be applied. If you want to avoid it, you’re free to implement your own in-app purchase infrastructure; Microsoft doesn’t force developers to use its services.

It’s important to highlight that in-app purchasing through Microsoft services is allowed only for virtual products (like new features, game levels, etc.); it can’t be used to buy physical goods.

Two kinds of products are supported by Windows Phone:

  • Durables are products that can be purchased just once, like application features, level packages, etc.
  • Consumables are products that can be purchased again after they’ve been consumed, like virtual coins.

Defining a Product

Products are defined in the portal. In the application’s page, the Products section offers an option to add new in-app products. Defining a product is similar to submitting an application: you have to set some basic properties like the name, price, and metadata, and then you submit it.

There are two key properties:

  • the product identifier, which is a unique ID that you use in your application to refer to the product
  • the product type, which can be consumable or durable

Interacting With Products

Once you’ve defined all the properties, you can start working with the products in your application. Probably, the first requirement is to display the list of available products users can buy. This goal is achieved using the CurrentApp class that belongs to the Windows.ApplicationModel.Store namespace.

The CurrentApp class exposes the LoadListingInformationAsync() method, which returns a ListingInformation object that stores all the information about the available products. 

Products are stored inside the ProductListings collection. In the previous sample, we display them to the user using a LongListSelector control, which has the following definition:

Every ProductListing object contains the same property we’ve assigned to the product in the Store. In the previous sample, we show the name (Name) and price (FormattedPrice) of the product.

Once you have the product list, you have to manage the purchase process. Again, we need to use the CurrentApp class, which offers the RequestProductPurchaseAsync() method. As a parameter, we’re going to pass the ProductListing object selected by the user.

Once a product is purchased, you can check its status by using the CurrentApp.LicenseInformation.ProductLicenses collection. It contains all the supported products with the related license status. Every product is identified by a key, which is the unique identifier we assigned when we created it in the portal.

In the previous sample, we can determine if the product with the CoolProduct identifier has been purchased by checking the value of the IsActive property. The operation is performed when the page is loaded: if the product has been purchased, we unlock the related feature, otherwise we’ll wait for the user to purchase it.

For a consumable product, the purchase process is the same. The only difference is that, after it’s been consumed, we need to report it so that it can be “unlocked” to be purchased again.

We can report it by calling the ReportProductFullfillment() method of the CurrentApp class, which requires as a parameter the ProductLicense object that identifies the product.

Testing In-App Purchases

Unfortunately, testing an in-app purchase is not very easy. Since products have to be defined in the portal, you’ll have to submit your application before being able to test the purchase process.

One work-around is to publish the application as beta; since the app doesn’t need to be certified, it will be immediately available for testing. The downside is that it’s hard to properly test it if something goes wrong since you can’t debug it using Visual Studio as you normally would with any other application.

For this reason, Microsoft has provided a testing library called MockIAP. Its purpose is to “mock” the real in-app purchase APIs so that the operations are not executed against the real Microsoft service, but use fake products that are defined within the application.

MockIAP can be downloaded from MSDN and added to your solution. The APIs it offers are the same as those exposed by the native SDK; the only difference is that they belong to the MockIAPLib namespace instead of the Windows.ApplicationModel.Store namespace.

There are two things to do to start using the MockIAP library. The first is to add some conditional compilations directives so that when the application is compiled in debug mode (typically during testing) it will use the mock library. When it’s compiled in release mode, it will use the real Microsoft services.

The following code sample shows how the namespace declaration will look in your page:

The second step is to define the products we need to use. Since the application won’t be connected to the real services, we need to duplicate in the code the products we’ve defined in the portal.

The following code shows a sample initialization:

We create two products: a durable one identified by the key CoolProduct, and a consumable one identified by the key CoolProductConsumable. Every product is identified by the ProductListing class (the same class we used with the real services), and we can use it to define all the product properties that are usually retrieved from Microsoft services like the name, type, price, and so on.

We add each product using the AddProductListing() method of the MockIAP class. After adding the products, we can use the standard APIs for in-app purchases. Operations will be performed locally with the fake products instead of the real services, but the behavior will be exactly the same. We’ll be able to list, buy, and consume the available products.

Conclusion

When we talk about mobile applications, development isn’t the only aspect we need to consider. If we want to be successful, we also have to distribute and promote our application. In this tutorial, we’ve discussed:

  • How to localize the application so that it appeals to a wider audience.
  • How the Windows Phone Store and the certification process work. Submitting the app is a crucial step since we have to make many important marketing decisions like the app’s price, the countries it will available in, etc.
  • How to increase revenue by supporting in-app purchases.

This tutorial represents the final chapter from Windows Phone 8 Succinctly, a free eBook from the team at Syncfusion. We hope you've enjoyed this series on developing applications for Windows Phone 8!

2015-04-23T15:31:06.000Z2015-04-23T15:31:06.000ZMatteo Pagani

Windows Phone 8 Succinctly: Localization, Windows Phone Store & In-App Purchases

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

When we talk about mobile applications, development isn't the only aspect we need to consider. If we want to be successful, we also have to distribute and promote our application. In this tutorial, we're going to discuss localization, the Windows Phone store, and in-app purchases.

Trial Apps

One of the distinctive features of Windows Phone applications is that they support a trial mode, which enables them to be downloaded from the Windows Phone Store as a trial with limited features. Once users decide to buy the full application, they don’t have to download it from scratch; the Store will simply download an updated certificate, which will unlock all the previously blocked features.

From the developer point of view, managing a trial is simple. The Windows.ApplicationModel.Store namespace contains a class called LicenseInformation, which offers a property called IsTrial. If its value is true, it means that the application has been installed in trial mode, so we have to lock the features we don’t want enabled; otherwise, the user has purchased it, so all features can be made available.

It’s up to you to choose the best trial experience for your application. For example, you can disable some features, limit the number of times the applications can be executed, or in a game, choose which levels to unlock.

Localization

One of the best ways to increase the sales and number of downloads of an application is to support multiple languages. The default Windows Phone 8 template in Visual Studio already supports localization by including a folder called Resources. It contains all resource files, which are simple XML files with a special .resx extension.

Resource files are simply a collection of values (the translated text) associated with a specific key which is used in the application to refer to that text. According to the user’s language, the application will automatically use the proper resource file.

The standard template creates a file called AppResources.resx inside the Resources folder, which refers to the standard language (usually English). 

Supporting a new language is easy. Just right-click your project in the Solution Explorer and choose Properties. The supported cultures box will display all the available languages. When you add new languages by selecting them in the list, Visual Studio will automatically create a new AppResources file named AppResources.xx-yy.resx in the Resources folder, where xx-yy is the culture code of the selected language (for example, if you’ve added Italian, it will create a file named AppResources.it-IT.resx).

Visual Studio offers a useful visual editor for working with resource files. It displays all the values inside a table, where you can easily define a key, its value, and an optional comment. To access it, simply double-click on a resource file in the Resources folder.

In addition to offering a standard resource file, the Windows Phone template also includes a class called LocalizedStrings, which acts as a wrapper between the localization file and the XAML. You can find it defined as a global resource in the App.xaml file:

Thanks to this wrapper, you’ll be able to access resources directly in XAML. You don’t have to add it directly in the XAML every time you need to display text in the user interface; instead you’ll add in the resource files and then connect them to your XAML with the following syntax:

Thanks to the LocalizedStrings class, we can access every value in the resource file simply by using the LocalizedResources.MyKey syntax, where MyKey is the key that identifies the text that you want to display.

If you want to access the resource string directly from code, you’ll have to use the AppResources singleton class, as shown in the following sample:

The Multilingual App Toolkit

Microsoft has created a useful Visual Studio extension called Multilingual App Toolkit, which can be downloaded from the Windows Dev Center. The tool doesn’t change how localization works; it will always be based on resource files, which are accessed by the application using the LocalizedString class.

The following list details some of the main benefits of the Multilingual App Toolkit:

  • One of the most time-consuming aspects of working with localization is manually copying all the new values you have added in the basic language to all other resource files. The Multilingual App Toolkit will do this for you. During the build process, it will copy all the new keys added to the AppResources.resx file to all the other resource files.
  • It offers a better visual interface for managing translations. You’ll be able to immediately identify the new keys to translate and set a different translation status.
  • It supports Bing services to automatically translate sentences. Obviously, you can’t completely rely on automatic translations, but they can be a good start for your localization process.
  • It’s able to automatically generate pseudo language, which is a way to immediately identify untranslated resources and have a better idea of how much space text occupies in the UI.

After you’ve installed the toolkit, you’ll have to enable it for your project in the Tools menu of Visual Studio by selecting the Enable multilingual app toolkit option. After enabling it, Visual Studio will work with .xlf files instead of .resx files (except for the main language). During the compilation process, the toolkit will generate all the required .resx files for you.

To access the toolkit visual interface, just double-click an .xlf file and you’ll see the complete list of resources. An icon will notify you of the status of each resource. If the resource has not yet been translated, a red circle is displayed. If the resource has been translated but requires revision, a yellow circle is displayed. If the translation has been approved, a green circle is displayed.

Multilingual App Toolkit

Forcing a Language

Windows Phone will automatically pick the resource file that matches the phone’s language. If an appropriate resource file is missing (because the phone’s language is not supported by your application), the default will be used.

You can change this behavior, for example, if you want to give users the option to choose the language they prefer, regardless of the phone’s language. To do this, you’ll need to set a different culture code when the App class (declared in the App.xaml.cs file) is created:

After you’ve defined a CultureInfo object by passing the culture code as a parameter, you can assign it to two different properties of the Thread.CurrentThread object:

  • CurrentCulture is the application’s culture, which is used to define features like date and time formats, currency, etc.
  • CurrentUICulture is the user interface culture, which is used to understand which resource file to pick.

This approach is also required if you want to use the pseudo language generated by the Multilingual App Toolkit during the testing process. Since pseudo language is not an official language supported by the platform, you’ll have to force it using the qps-ploc culture code, as shown in the following sample:

Using pseudo language is a great way to identify text that has yet to be translated and test whether your application’s layout is able to manage long text. What typically happens when developing an application is that you test it with only a couple languages, forgetting that a word that looks very short in English, for example, can be very long when it’s translated to German.

The Store Experience

As mentioned in the first article, the Windows Phone Store is the only way to distribute applications to your users unless you’re pursuing enterprise distribution. You’ll need a paid developer account, which can be purchased from the Windows Dev Center. The fee is $19 per year, unless you’re a student subscribed to the DreamSpark program, in which case access is free. A similar benefit is granted to MSDN subscribers: in the benefits page, you can get a token that allows you to register for free.

Other than the annual fee, Microsoft applies a revenue-sharing approach: 30% of the application’s price is kept by Microsoft, while the other 70% is given to the developer. Of course, this sharing doesn’t apply if the app is free.

Once your developer account has been activated and your application is ready, you can submit it to the portal at dev.windowsphone.com. During the process, you’ll have to define the application marketing features, like price, metadata, and distribution type. After that, the submission is completed, and the certification process starts. Applications are not automatically published to the Store; first they need to pass a certification process that validates the application both from a technical and content point of view.

The technical tests make sure that the application offers a good experience to users: it doesn’t crash, it’s fast and responsive, and the user interface is not confusing.

The manual tests check the content of the application. Some types of content like pornography, excessive violence, etc., are not allowed and will lead to a certification failure.

When you start the submission process, you’ll see a list of steps to follow to complete the process. Let’s briefly look at each step.

Step 1: App Info

The first step of the publishing process is used to set some basic information, like the app’s category, price tier, and market distribution. Your application will automatically be distributed in all the supported countries at the price you’ve chosen. The price will be automatically converted into each country’s currency. 

In this step, you can choose to automatically exclude countries like China, where the content policies are stricter. The certification process also offers an optional Market selection and custom pricing step, which offers deeper customization: you can choose to distribute the applications only in specific countries and customize the price for each country.

The other important option to set during this step is the distribution channel. There are three ways to distribute a Windows Phone application:

  • The public store: The app can be discovered and downloaded by any user.
  • Hidden: The app is still available in the public store, but it can’t be discovered by users. The only way to find it is by using the direct link that is generated when the app is published.
  • Beta: The application can’t be discovered by users, and moreover, only authorized users will be allowed to download it. Users are authorized with the Microsoft account they registered the phone with. You’ll be able to include up to 10,000 users during the submission process. This distribution channel was created to support beta testing; in this scenario, however, the application won’t actually be tested, but will be available to the selected users within two hours of submitting the app. A beta application automatically expires 90 days after it’s been submitted for the first time, regardless of later updates.

Step 2: Upload and Describe Your XAP

The second step requires more time to complete, since you’ll have to provide all the application information that will be displayed in the Windows Phone Store.

The first step is to upload the XAP file. The XAP is the package produced by Visual Studio when you compile your project, and it contains all the required files for the application to run. You’ll find it inside the bin folder of your Visual Studio project. Remember to always compile the application in release mode; otherwise it won’t be accepted.

Once you’ve uploaded the XAP, the portal will automatically display a recap of the application’s features, like the supported resolutions, the required capabilities, and so on. You’ll also have to set the version number of the application you’re uploading.

The portal will also automatically detect the languages you support, which will be displayed in a drop-down menu called Language details. You’ll have to set the application’s metadata (title, description, and keywords) for every supported language. This information will be displayed in the Store when the user opens your application’s page.

Information about the App Displayed in the Store

You will also need to upload at least one screenshot (eight are allowed) for every language and supported resolution, plus the application icon. They will be displayed in the screenshots section of the Store. To take screenshots, you can use one of the tools available in the emulator.

Once you’ve completed all the required steps, the portal will show you a recap of the submission for your confirmation.

Managing the Application’s Life Cycle

Once your application has been certified, you’ll have access to many reports that will help you understand how well your application is performing. There are download reports, sales reports, and crash reports.

If the application doesn’t pass the certification process, you’ll find in your dashboard a PDF file containing the full report. It will tell you in detail what went wrong and what you should do to fix the identified problems.

In the end, of course, you can also update your application. In this case you’ll simply have to repeat all the submission steps, although all the fields will already be filled with the old information and metadata. The process is also the same if you just want to change information like the price, description, and screenshots. The submission only has to be certified if you’ve changed any information that needs to be validated. If you only change the price, the update is immediately published.

In-App Purchases

A different way to make money with Windows Phone apps is to support in-app purchases. In addition to buying the app from the Store, users can also make purchases within the application itself.

In-app purchases have always been allowed, but Windows Phone 8 has introduced specific APIs and Microsoft backend support. Previously, the developer was in charge of creating the server infrastructure, managing payments, and connecting the client.

Now, you can simply rely on the Store infrastructure. Users will pay using the same credit card they used to purchase apps or music from the Store, and the portal will allow you to create one or more products to buy within the application. Also in this case, the revenue-sharing approach will be applied. If you want to avoid it, you’re free to implement your own in-app purchase infrastructure; Microsoft doesn’t force developers to use its services.

It’s important to highlight that in-app purchasing through Microsoft services is allowed only for virtual products (like new features, game levels, etc.); it can’t be used to buy physical goods.

Two kinds of products are supported by Windows Phone:

  • Durables are products that can be purchased just once, like application features, level packages, etc.
  • Consumables are products that can be purchased again after they’ve been consumed, like virtual coins.

Defining a Product

Products are defined in the portal. In the application’s page, the Products section offers an option to add new in-app products. Defining a product is similar to submitting an application: you have to set some basic properties like the name, price, and metadata, and then you submit it.

There are two key properties:

  • the product identifier, which is a unique ID that you use in your application to refer to the product
  • the product type, which can be consumable or durable

Interacting With Products

Once you’ve defined all the properties, you can start working with the products in your application. Probably, the first requirement is to display the list of available products users can buy. This goal is achieved using the CurrentApp class that belongs to the Windows.ApplicationModel.Store namespace.

The CurrentApp class exposes the LoadListingInformationAsync() method, which returns a ListingInformation object that stores all the information about the available products. 

Products are stored inside the ProductListings collection. In the previous sample, we display them to the user using a LongListSelector control, which has the following definition:

Every ProductListing object contains the same property we’ve assigned to the product in the Store. In the previous sample, we show the name (Name) and price (FormattedPrice) of the product.

Once you have the product list, you have to manage the purchase process. Again, we need to use the CurrentApp class, which offers the RequestProductPurchaseAsync() method. As a parameter, we’re going to pass the ProductListing object selected by the user.

Once a product is purchased, you can check its status by using the CurrentApp.LicenseInformation.ProductLicenses collection. It contains all the supported products with the related license status. Every product is identified by a key, which is the unique identifier we assigned when we created it in the portal.

In the previous sample, we can determine if the product with the CoolProduct identifier has been purchased by checking the value of the IsActive property. The operation is performed when the page is loaded: if the product has been purchased, we unlock the related feature, otherwise we’ll wait for the user to purchase it.

For a consumable product, the purchase process is the same. The only difference is that, after it’s been consumed, we need to report it so that it can be “unlocked” to be purchased again.

We can report it by calling the ReportProductFullfillment() method of the CurrentApp class, which requires as a parameter the ProductLicense object that identifies the product.

Testing In-App Purchases

Unfortunately, testing an in-app purchase is not very easy. Since products have to be defined in the portal, you’ll have to submit your application before being able to test the purchase process.

One work-around is to publish the application as beta; since the app doesn’t need to be certified, it will be immediately available for testing. The downside is that it’s hard to properly test it if something goes wrong since you can’t debug it using Visual Studio as you normally would with any other application.

For this reason, Microsoft has provided a testing library called MockIAP. Its purpose is to “mock” the real in-app purchase APIs so that the operations are not executed against the real Microsoft service, but use fake products that are defined within the application.

MockIAP can be downloaded from MSDN and added to your solution. The APIs it offers are the same as those exposed by the native SDK; the only difference is that they belong to the MockIAPLib namespace instead of the Windows.ApplicationModel.Store namespace.

There are two things to do to start using the MockIAP library. The first is to add some conditional compilations directives so that when the application is compiled in debug mode (typically during testing) it will use the mock library. When it’s compiled in release mode, it will use the real Microsoft services.

The following code sample shows how the namespace declaration will look in your page:

The second step is to define the products we need to use. Since the application won’t be connected to the real services, we need to duplicate in the code the products we’ve defined in the portal.

The following code shows a sample initialization:

We create two products: a durable one identified by the key CoolProduct, and a consumable one identified by the key CoolProductConsumable. Every product is identified by the ProductListing class (the same class we used with the real services), and we can use it to define all the product properties that are usually retrieved from Microsoft services like the name, type, price, and so on.

We add each product using the AddProductListing() method of the MockIAP class. After adding the products, we can use the standard APIs for in-app purchases. Operations will be performed locally with the fake products instead of the real services, but the behavior will be exactly the same. We’ll be able to list, buy, and consume the available products.

Conclusion

When we talk about mobile applications, development isn’t the only aspect we need to consider. If we want to be successful, we also have to distribute and promote our application. In this tutorial, we’ve discussed:

  • How to localize the application so that it appeals to a wider audience.
  • How the Windows Phone Store and the certification process work. Submitting the app is a crucial step since we have to make many important marketing decisions like the app’s price, the countries it will available in, etc.
  • How to increase revenue by supporting in-app purchases.

This tutorial represents the final chapter from Windows Phone 8 Succinctly, a free eBook from the team at Syncfusion. We hope you've enjoyed this series on developing applications for Windows Phone 8!

2015-04-23T15:31:06.000Z2015-04-23T15:31:06.000ZMatteo Pagani

Design Patterns: Singletons

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

Design patterns are often considered a more advanced topic and therefore ignored or overlooked by people new to iOS or OS X development. However, there are a number of design patterns every aspiring iOS or OS X developer will be faced with from day one. The singleton pattern is one such pattern.

Before we start looking at techniques to implement the singleton pattern in Swift and Objective-C, I'd like to take a moment to understand the singleton pattern, including its advantages and disadvantages.

1. What Is a Singleton?

True & Functional Singletons

The singleton pattern is inextricably tied to object-oriented programming. The definition of the singleton pattern is simple, only one instance of the singleton class can be created or is alive at any one time.

Brent Simmons, however, nuances this definition by making a distinction between true singletons and functional singletons. Brent defines true singletons as classes that always return the same instance of itself. It is not possible to create more than one instance of the class. Functional singletons are created once and used in several places.

I'm sure many developers wouldn't categorize functional singletons as singletons, but I like the distinction Brent makes. Functional singletons often lack the disadvantages typical to true singletons. We'll look at these disadvantages later in this article.

If you're familiar with iOS or OS X development, then you'll notice that Apple's frameworks make use of the singleton pattern. An iOS application, for example, can only have one instance of the UIApplication class, which you can access through the sharedApplication class method.

Even though the UIApplication class gives you access to the UIApplication singleton, nothing prevents you from explicitly instantiating a UIApplication instance.

The result, however, is a runtime exception. The exception clearly states that only one instance of the UIApplication class can be alive at any one time. In other words, the UIApplication class was designed with the singleton pattern in mind.

Advantages

Accessibility

The most obvious advantage of the singleton pattern is accessibility. Consider the UIApplication class as an example. By importing the UIKit framework, the UIApplication singleton is accessible from anywhere in your project. Take a look at the following example of a UIViewController subclass.

Control and Behavior

It is sometimes useful or essential that only one instance of a class is alive at any one time. The UIApplication class is an example of this requirement. Other examples may include classes for logging, caching, or I/O operations.

That said, it is important to understand that singletons are a means to accomplish control and behavior. Defensive coding techniques can give you the same result without the mental overhead of the singleton pattern.

Disadvantages

Global State

By creating a singleton, you're essentially creating global state. It's important that you're aware of this. A few years ago, Miško Hevery wrote a great article about the singleton pattern in which he explains why the pattern should be avoided. Miško emphasizes that global state is the main reason why singletons are harmful.

There are exceptions though. For example, singletons that are immutable can do little harm. You're still creating global state, but that state is immutable. Miško also mentions loggers as a—somewhat—acceptable application of the singleton pattern since state flows in one direction, from your application into the logger.

Tight Coupling

Most object-oriented programming languages consider tight coupling of modules a bad practice. Put differently, it is recommended to decouple modules as much as possible. This puts the singleton pattern in a bad place and singletons are therefore considered a bad practice by many respected programmers. Some developers go as far as considering it an anti-pattern that should be avoided.

To better understand the problem, consider the following scenario. You've created an iOS application with a networking component in which you access the UIApplication singleton. Your iOS application is such a success that you consider creating an OS X application. The UIApplication class, however, is not available on OS X due to the lack of the UIKit framework. This means that you will have to refactor or modify the networking component of the iOS application.

There are a number of solutions to solve this problem, but the point I want to make is that you have tightly coupled the networking module to the UIKit framework, the UIApplication class in particular.

Reusability

Tight coupling is often closely associated with reusability. A tightly coupled object graph is very often difficult to reuse without refactoring. Poor reusability is sometimes unavoidable, but it is certainly something to keep in mind when developing software.

2. Creating a Singleton

Objective-C

Creating a singleton in Objective-C is very easy to do. In the following code snippet, we create and implement a logging class, Logger. We access the singleton object through the sharedLogger class method.

The implementation is simple. We declare a static variable _sharedInstance that will hold a reference to the singleton object. We invoke dispatch_once, a Grand Central Dispatch function, and pass in a block in which we initialize an instance of the Logger class. We store a reference to the instance in _sharedInstance.

The dispatch_once function ensures that the block we pass it is executed once for the lifetime of the application. This is very important since we only want to initialize one instance of the Logger class.

The oncePredicate variable that is passed as the first argument of the dispatch_once function is used by the dispatch_once function to ensure that the block is executed only once.

The sharedLogger class method returns the Logger instance by returning the reference stored in _sharedInstance. The implementation of sharedLogger may look daunting at first, but I'm sure you agree that the idea is very simple.

Swift

To implement the singleton pattern in Swift, we make use of class constants, which were introduced in Swift 1.2. If you are having issues with the below code snippet, then make sure that you are using Xcode 6.3+.

Let me walk you through the short implementation of the Logger class. We start by declaring a class named Logger. To implement the singleton pattern, we declare a type property, sharedInstance, of type Logger.

By using the static keyword, the sharedInstance constant is tied to the Logger class instead of instances of the class. The sharedInstance constant is referred to as a type property since it is tied to the type, that is, the Logger class. We access the singleton object through the Logger class.

You may be wondering why we don't use the dispatch_once function like we did in the Objective-C implementation. Under the hood, Swift already uses dispatch_once when initializing static constants. That's something you get for free in Swift.

Another common approach for implementing the singleton pattern is by leveraging nested types. In the following example, we declare a computed type property, sharedInstance, of type Logger. In the closure of the computed type property, we declare a structure named Singleton. The structure defines a constant type property, instance, of type Logger.

Accessing the singleton object is the same for both strategies. If you are using Swift 1.2, then I recommend using the first approach for its brevity and simplicity.

3. When To Use Singletons?

I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail. — Abraham Maslow

When I first heard about the singleton pattern, I was excited about how useful it would be in my next project. It is very tempting to use a tool that seems to solve many problems. At first glance, the singleton pattern may look like a silver bullet or a golden hammer, but that is not what the singleton pattern is.

For example, if you're using a singleton only to make it easily accessible, then you may be using the singleton pattern for the wrong reasons. It's not because Apple uses the singleton pattern in its own frameworks that it is the right solution to every problem.

Singletons can be very useful, but they are considered an anti-pattern by many experienced programmers. Most of them have had bad experiences with the pattern to come to that conclusion. Learn from their mistakes and use them sparingly.

I don't consider the singleton pattern an anti-pattern, but it is a pattern that should be used with caution. If you feel tempted to turn an object into a singleton, ask yourself the question if there is any other way that you could solve the problem. In most cases, the singleton pattern isn't the only solution available. An alternative solution may require more work or a bit of overhead, but it is probably better in the long run.

The functional singletons Brent Simmons refers to are often a perfectly valid alternative to true singletons. There's nothing wrong with creating an instance of a class and passing it to the objects that need it. Consider this approach the next time you are about the create another singleton.

Conclusion

The singleton pattern is simple and powerful, but it should be used sparingly. Some of your colleagues may advise you against it, but I think it's important to consider its use and judge for yourself whether you think it's a useful addition to your toolbox.

2015-04-27T17:41:24.877Z2015-04-27T17:41:24.877ZBart Jacobs

An Introduction to CloudKit

$
0
0

Introduction

CloudKit is an Apple framework that was introduced alongside iOS 8 in 2014. It's purpose is to provide a simple solution for storing your application's data in the cloud using iCloud, making it available across devices. Some of the key features of CloudKit include:

  • up to 1 PB of asset storage (images, audio files, etc.)
  • up to 10 TB of database storage (strings, numbers, arrays, etc.)
  • iCloud user authentication
  • notifications

In this tutorial, I will teach you how to set up and interact with CloudKit in an iOS application by creating a sample application called CloudBug. CloudBug displays a list of bugs with a title and a description, which are stored in iCloud using CloudKit.

Requirements

This tutorial requires that you are running Xcode 6+ and have an iOS developer account. You will also need to download the starter project from GitHub.

1. Project Configuration

The first thing you need to do after opening the starter project is changing the target's bundle identifier and team. Select the CloudBug project in the Project Navigator and choose the CloudBug target from the list of targets.

Configuring the CloudBug Target

Change the bundle identifier to a unique string using reverse domain name service notation. Next, select the appropriate team for your developer account.

Open the Capabilities tab at the top and enable iCloud by toggling the switch on the right. This will reveal the iCloud settings for the CloudBug target.

Enabling iCloud for the CloudBug Target

In the iCloud settings, check the checkbox labeled CloudKit to enable CloudKit for the CloudBug target.

Enabling CloudKit for the CloudBug Target

Build and run the application on a physical device on in the iOS Simulator to see if everything is working without errors.

2. Creating the Bug Record Type

Click the CloudKit Dashboard button at the bottom of the iCloud settings. This will open the CloudKit dashboard in your browser. After logging in with your developer account, the CloudKit dashboard should appear. Before continuing, let me walk you through the items in the sidebar on the left.

Opening the CloudKit Dashboard

Schema

  • Record Types function similarly to a regular class definition. Records are created like class instances from these types.
  • Security Roles provide a way to let different users access data in different ways. For example, a security role could be used to allow only admin level users read and write permission for data.
  • Subscription Types are used to manage the different subscriptions your app has if these have been implemented.

Public Data

  • User Records work just like regular records except that they are specifically linked to the Users record type, which can not be deleted.
  • Default Zone is where all of your public records and other data will be stored.

Private Data

  • Default Zone works just like the public default zone, except that it is only accessible to the user who is currently logged in.

Admin

  • Team where you can view other developers collaborating on the project and edit their permissions.
  • Deployment where you can view what changes will be made to the schema items when your project enters a production environment.

In this tutorial, you are only going to be focusing on record types and the public default zone. The next step is to create your first record type.

If you select Record Types from the sidebar on the left, you will notice that a type named Users already exists.

The User Record Type Is a Default Record Type

Let's create a new record type named Bug that will contain a title and description. Click the plus button at the top to create a new record type.

Creating a New Record Type

Change the new record type's name to Bug and add two attributes, Title and Description. Make both attributes of type String with only the Query index option checked. This is what the new record type should look like.

This Is What the New Record Type Should Look Like

Click Save in the bottom right to create the Bug record type.

Create the Bug Record Type by Clicking Save

3. Creating Records in CloudKit Dashboard

When you select Default Zone under Public Data, the Bug record type should already be selected. Create a new record either by clicking New Record or by clicking the plus button at the top.

Create a New Record

Enter whatever you want for the record's Description and Title fields.

Add Data to the New Record

Click Save in the bottom right to create the record. You'll see that your record has been assigned a unique record IDCreated date, Modified date, Created By identifier, and Modified By identifier. No matter what record type a record is based on, it will always have these five attributes.

4. Loading Records

Head back to Xcode and open MasterViewController.swift. At the top, add an import statement to import the CloudKit framework.

Update the viewDidLoad method by appending the following code snippet.

Let's see what's happening in this code snippet.

  • First, we get a reference to the default container for your application. This container contains the record types and records we created in the CloudKit dashboard. You can create more containers with a unique identifier in the Target Inspector > Capabilities.
  • Second, we obtain a reference to the container's public database. The format is the same for the private database.
  • We then create a query for the Bug record type using an NSPredicate instance. This predicate can be used to filter the results of the query, for example, only fetching records created or modified after a certain date. For this example, we fetch every record of type Bug.
  • Next, we tell the database to perform the query, which triggers an asynchronous request. When the request is completed, the completion block is executed, handing us a results array and an error object.
  • If the error object is nil, we loop through the elements of the results array and create a local Bug instance for each record. Each Bug instance is added to the table view's data source and the table view is reloaded on the main thread.

Build and run your application to see if the record we created in the CloudKit dashboard is loaded into CloudBug.

Loading Records Into CloudBug

If you see an error in Xcode's console similar to the one below, then make sure that you are logged in to the correct iCloud account on your test device. This is also true if you're running CloudBug in the iOS Simulator.

Make Sure You Are Logged in to iCloud

Tapping the bug in the table view should present the detail view controller with the bug's description.

Showing the Bugs Description

5. Creating Records

While loading data from iCloud through CloudKit can be very useful, CloudBug also needs the ability to allow users to create new records. In MasterViewController.swift, add the following code snippet to the receiveBug(_:) method.

The first two lines should be familiar. We obtain a reference to the default container and the public database. We create a CKRecord instance, set values for the Title and Description keys, and save the record to iCloud.

Note that the record object returned from iCloud in the saveRecord(_:completionHandler:) completion handler includes the values you set manually as well as the five default attributes we saw earlier in the CloudKit dashboard.

Build and run your application, and post a new bug by tapping the plus button in the top right, filling in the title and description fields. Tap Post and to save the new record in iCloud in the CloudKit database.

Create a New Bug Record

Revisit the CloudKit dashboard and navigate to the Default Zone under Public Data. If all went well, you should see two Bug records in the database.

The New Record Shows Up in the CloudKit Dashboard

6. Deleting Records

Let's finish this tutorial by enabling users to delete a bugs. Add the following code snippet to the tableView(_:commitEditingStyle:forRowAtIndexPath:) method just above objects.removeAtIndex(indexPath.row).

To delete a record, we create a query as we did earlier. To delete a record, however, we create a predicate to match the bug's title and description. The completion handler returns the results of the query which we use to delete corresponding record from the public database.

Build and run the application, and delete one of the bugs either by swiping to the right or by tapping the Edit button.

Deleting Records

Revisit the CloudKit dashboard to see if the bug you selected has indeed been deleted.

Conclusion

In this tutorial, you created your first CloudKit application by linking your application to iCloud. You learned how to create record types and records in the CloudKit dashboard, and how to load them in your application. In addition to adding and deleting records in the CloudKit dashboard, we also covered adding and deleting records using the CloudKit framework. If you have any comments or questions, leave them in the comments below.

2015-04-29T16:45:16.000Z2015-04-29T16:45:16.000ZDavis Allie

An Introduction to CloudKit

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

Introduction

CloudKit is an Apple framework that was introduced alongside iOS 8 in 2014. It's purpose is to provide a simple solution for storing your application's data in the cloud using iCloud, making it available across devices. Some of the key features of CloudKit include:

  • up to 1 PB of asset storage (images, audio files, etc.)
  • up to 10 TB of database storage (strings, numbers, arrays, etc.)
  • iCloud user authentication
  • notifications

In this tutorial, I will teach you how to set up and interact with CloudKit in an iOS application by creating a sample application called CloudBug. CloudBug displays a list of bugs with a title and a description, which are stored in iCloud using CloudKit.

Requirements

This tutorial requires that you are running Xcode 6+ and have an iOS developer account. You will also need to download the starter project from GitHub.

1. Project Configuration

The first thing you need to do after opening the starter project is changing the target's bundle identifier and team. Select the CloudBug project in the Project Navigator and choose the CloudBug target from the list of targets.

Configuring the CloudBug Target

Change the bundle identifier to a unique string using reverse domain name service notation. Next, select the appropriate team for your developer account.

Open the Capabilities tab at the top and enable iCloud by toggling the switch on the right. This will reveal the iCloud settings for the CloudBug target.

Enabling iCloud for the CloudBug Target

In the iCloud settings, check the checkbox labeled CloudKit to enable CloudKit for the CloudBug target.

Enabling CloudKit for the CloudBug Target

Build and run the application on a physical device on in the iOS Simulator to see if everything is working without errors.

2. Creating the Bug Record Type

Click the CloudKit Dashboard button at the bottom of the iCloud settings. This will open the CloudKit dashboard in your browser. After logging in with your developer account, the CloudKit dashboard should appear. Before continuing, let me walk you through the items in the sidebar on the left.

Opening the CloudKit Dashboard

Schema

  • Record Types function similarly to a regular class definition. Records are created like class instances from these types.
  • Security Roles provide a way to let different users access data in different ways. For example, a security role could be used to allow only admin level users read and write permission for data.
  • Subscription Types are used to manage the different subscriptions your app has if these have been implemented.

Public Data

  • User Records work just like regular records except that they are specifically linked to the Users record type, which can not be deleted.
  • Default Zone is where all of your public records and other data will be stored.

Private Data

  • Default Zone works just like the public default zone, except that it is only accessible to the user who is currently logged in.

Admin

  • Team where you can view other developers collaborating on the project and edit their permissions.
  • Deployment where you can view what changes will be made to the schema items when your project enters a production environment.

In this tutorial, you are only going to be focusing on record types and the public default zone. The next step is to create your first record type.

If you select Record Types from the sidebar on the left, you will notice that a type named Users already exists.

The User Record Type Is a Default Record Type

Let's create a new record type named Bug that will contain a title and description. Click the plus button at the top to create a new record type.

Creating a New Record Type

Change the new record type's name to Bug and add two attributes, Title and Description. Make both attributes of type String with only the Query index option checked. This is what the new record type should look like.

This Is What the New Record Type Should Look Like

Click Save in the bottom right to create the Bug record type.

Create the Bug Record Type by Clicking Save

3. Creating Records in CloudKit Dashboard

When you select Default Zone under Public Data, the Bug record type should already be selected. Create a new record either by clicking New Record or by clicking the plus button at the top.

Create a New Record

Enter whatever you want for the record's Description and Title fields.

Add Data to the New Record

Click Save in the bottom right to create the record. You'll see that your record has been assigned a unique record IDCreated date, Modified date, Created By identifier, and Modified By identifier. No matter what record type a record is based on, it will always have these five attributes.

4. Loading Records

Head back to Xcode and open MasterViewController.swift. At the top, add an import statement to import the CloudKit framework.

Update the viewDidLoad method by appending the following code snippet.

Let's see what's happening in this code snippet.

  • First, we get a reference to the default container for your application. This container contains the record types and records we created in the CloudKit dashboard. You can create more containers with a unique identifier in the Target Inspector > Capabilities.
  • Second, we obtain a reference to the container's public database. The format is the same for the private database.
  • We then create a query for the Bug record type using an NSPredicate instance. This predicate can be used to filter the results of the query, for example, only fetching records created or modified after a certain date. For this example, we fetch every record of type Bug.
  • Next, we tell the database to perform the query, which triggers an asynchronous request. When the request is completed, the completion block is executed, handing us a results array and an error object.
  • If the error object is nil, we loop through the elements of the results array and create a local Bug instance for each record. Each Bug instance is added to the table view's data source and the table view is reloaded on the main thread.

Build and run your application to see if the record we created in the CloudKit dashboard is loaded into CloudBug.

Loading Records Into CloudBug

If you see an error in Xcode's console similar to the one below, then make sure that you are logged in to the correct iCloud account on your test device. This is also true if you're running CloudBug in the iOS Simulator.

Make Sure You Are Logged in to iCloud

Tapping the bug in the table view should present the detail view controller with the bug's description.

Showing the Bugs Description

5. Creating Records

While loading data from iCloud through CloudKit can be very useful, CloudBug also needs the ability to allow users to create new records. In MasterViewController.swift, add the following code snippet to the receiveBug(_:) method.

The first two lines should be familiar. We obtain a reference to the default container and the public database. We create a CKRecord instance, set values for the Title and Description keys, and save the record to iCloud.

Note that the record object returned from iCloud in the saveRecord(_:completionHandler:) completion handler includes the values you set manually as well as the five default attributes we saw earlier in the CloudKit dashboard.

Build and run your application, and post a new bug by tapping the plus button in the top right, filling in the title and description fields. Tap Post and to save the new record in iCloud in the CloudKit database.

Create a New Bug Record

Revisit the CloudKit dashboard and navigate to the Default Zone under Public Data. If all went well, you should see two Bug records in the database.

The New Record Shows Up in the CloudKit Dashboard

6. Deleting Records

Let's finish this tutorial by enabling users to delete a bugs. Add the following code snippet to the tableView(_:commitEditingStyle:forRowAtIndexPath:) method just above objects.removeAtIndex(indexPath.row).

To delete a record, we create a query as we did earlier. To delete a record, however, we create a predicate to match the bug's title and description. The completion handler returns the results of the query which we use to delete corresponding record from the public database.

Build and run the application, and delete one of the bugs either by swiping to the right or by tapping the Edit button.

Deleting Records

Revisit the CloudKit dashboard to see if the bug you selected has indeed been deleted.

Conclusion

In this tutorial, you created your first CloudKit application by linking your application to iCloud. You learned how to create record types and records in the CloudKit dashboard, and how to load them in your application. In addition to adding and deleting records in the CloudKit dashboard, we also covered adding and deleting records using the CloudKit framework. If you have any comments or questions, leave them in the comments below.

2015-04-29T16:45:16.000Z2015-04-29T16:45:16.000ZDavis Allie

Creating a Dating Application with Sinch: Integrating Sinch

$
0
0

Dating apps have become one of the more popular genres in the App Store recently. Due to their nature, however, developing a fully featured dating app can be challenging. In the second part of this series, we'll look at how we can leverage the Sinch platform in an iOS app to implement voice calls and messaging. These are two cornerstone features for dating apps and they are surprisingly easy to implement with Sinch.

1. Overview

Before we begin coding, let's review the app we are making. Our dating app will have a few core features that we'll focus on in this tutorial. For accounts, users will be able to sign in using Facebook. After signing in, they'll be able to see other users of the app that are nearby.

The users are stored on the server that we communicate with from the restful API created in the first part of this tutorial. Once we get the user's information from Facebook, a new user is posted to the server and a session created. After that, a list of registered users will be retrieved to select from.

When the user finds someone they want to talk to, they will be able to either message them or initiate a voice call. This is where Sinch will come into play. We'll utilize their SDK to do all of the hard work of handling voice calls and messaging.

Now that we know what we are developing, it's time to get started.

2. Starter Project

Start by downloading the starter project from GitHub. The app is targeted at iPhone and it contains the user interface, Facebook authentication, and communication with the RESTful API already in place. This will allow us to focus on integrating with Sinch.

Before we continue, though, I'd like to discuss the basic architecture of the app and how it communicates with the server. The code that communicates with the rest API lives in the UsersAPIClient class. It uses the popular AFNetworking library to simplify the networking logic. If you've used AFNetworking before, this will look very familiar to you. If you haven't, our tutorial about AFNetworking is an excellent place to start.

In the header file, you'll see some methods to communicate with various endpoints of the RESTful API, such as creating a user, starting a session, deleting a user, and more.

When a response comes back from the server, the JSON is parsed and used to initialize a model.

Speaking of models, there is one model used in the project, User. It contains basic information about a user, such as name, location, id, etc. The user id is especially important since we'll need it to uniquely identify who we are communicating with when we integrate with Sinch.

Take a few moments to browse the project to get a better understanding of its structure. Just like with third party libraries, it's tremendously helpful to browse documentation and source code before you actually use it.

3. Build and Run 

If you build and run the demo project, you should be prompted to log in via Facebook.

Log In with Facebook

Go ahead and check if you can log in with Facebook. After logging in, the demo app does three things:

  • It creates a user record on the backend if one isn't present.
  • It starts a user session and creates an access token for the session.
  • It retrieves a list of users in the system.

Later on, when you've made a few test accounts, you can find users within a certain range. By default, every user in the system is returned since it's unlikely any other users are nearby while you're testing.

4. Create a Sinch Account

To use the Sinch SDK, you'll first need to create a developer account. Head over to the Sinch website and click Get Started For Free in the top right to sign up.

Sign Up for a Free Sinch Account

Enter your email address and password, and accept the terms and conditions. Sinch will automatically start a setup process after you sign up. At this point, all you need to do is name your app and add a short description. You can skip the rest of the start guide for now.

Next, visit the dashboard to retrieve your app's API key and secret. You should see Dashboard at the top of Sinch's website after you've signed in with your new account. Select Apps on the left, select the app you created, and click the keys icon on the right to show the key and secret. You'll want to keep track of these values to later initialize the Sinch client.

Finding Your Apps Key and Secret

5. Add Sinch SDK

There are two ways to add the Sinch SDK to your project. The easiest approach by far is through CocoaPods. Add the following line to your Podfile:

Next, run the following command to integrate the Sinch SDK into your workspace:

In this tutorial, however, I'll show you how to add the SDK if you're not using CocoaPods. Start by downloading the Sinch SDK for iOS. Visit the downloads section of the Sinch website and download the SDK for iOS. The Sinch SDK depends on three frameworks so we'll need to link our project against those first. In the Project Navigator, choose SinchTutorial and select the SinceTutorial target.

Select the SinchTutorial Target

 Select Build Phases > Link Binary With Libraries and click the plus button at the bottom.

Add Libraries

Add the following frameworks to the list of frameworks to link with:

  • Security
  • AudioToolbox
  • AVFoundation

We also need to add three linker flags. In the target's Build Settings, search for Other Linker Flags.

Add Other Linker Flags

Add the following linker flags under Debug:

Finally, drag the Sinch framework that you downloaded earlier into the Frameworks folder in the Project Navigator. Build your project to make sure there are no errors. You're now ready to start using the Sinch SDK.

6. Setting Up the Sinch Client

The Sinch client is the driving force responsible for communicating with the Sinch platform. Before we can use the messaging or calling features, we'll need to initialize an instance of the Sinch client. To do this, we need the key and secret that we retrieved earlier after creating our Sinch account.

Open AppDelegate.h and import the Sinch framework as shown below.

Next, we need to create a property for the Sinch client and a method prototype for initializing it. Add the following code snippet below the window property.

We'll use this reference to the Sinch client to easily get calls and messaging going. The SINClientDelegate protocol will inform us whether connecting with the Sinch backend was successful.

Conform the AppDelegate class to the SINClientDelegate protocol as shown below.

Switch to the implementation file of the AppDelegate class and implement the sinchClientWithUserId: method as shown below.

We'll use this method later to communicate with the Sinch backend after the user has logged in. Remember to enter the application key and secret. Otherwise you'll be unable to connect to the Sinch backend.

After initializing the client, we tell Sinch that we'll be using the messaging and calling features. We then start the client and establish a connection with the Sinch services to receive incoming calls.

Next, implement the following delegate methods of the SINClientDelegate protocol in the AppDelegate class:

These delegate methods will log errors to the Xcode console should any occur and they also inform us when we've successfully connected with Sinch.

7. Initializing the Sinch Client

Open FindUsersViewController.m and scroll to the beginUserSession method. In this method, if a session was started without errors the completion block is executed. This is a good time to initialize the Sinch client. Replace the //TODO comment with the following code block:

This calls the method to start the Sinch client and allows us to start using its features. Build and run the app. After you've retrieved a list of users, confirm that connecting with the Sinch backend was successful by checking the logs in the Xcode console.

8.  Implement Messaging

We're now getting to the fun part, adding a messaging component with very little code using the Sinch SDK. Start by opening MessagingViewController.m and import the Sinch framework.

Much like the SINClientDelegate protocol provides helpful methods that help us keep track of the client's status, the SINMessageClientDelegate protocol keeps us informed about incoming and outgoing messages, their status, and more.

Start by conforming the MessagingViewController class to this protocol by updating the interface of the class.

To implement messaging, we'll also need a SINMessageClient instance to handle the responsibilities of messaging. Add a property for the SINMessageClient instance.

We can create an instance of a messaging client from the Sinch client we already have in the app delegate. When the view controller loads, we need to initialize one and set the view controller as its delegate. Add the following code block to the view controller's viewDidLoad method:

Now that we've got an object to send and receive messages, and a delegate to handle them, let's add code to compose a message. Find the sendMessage: method at the bottom of the view controller and add the following implementation:

A SINOutgoingMessage instance will contact Sinch and move the message over to the recipient. We designate the recipient by providing their user id from the user's model. Sinch will know where to go with the message by routing it through their API using a combination of your application key, secret, and the unique user id passed to it.

Since a message could either be incoming or outgoing, add an enum at the top of the view controller to account for either scenario. Add it below the import statements.

Finally, we'll need the messaging client to actually process and send the message. In this view controller, we'll need to handle both sending and receiving messages. Add the following code snippet to receive a message:

Whenever we receive a message, we'll add it to the messages array and reload the table view to display it. It's important to note that the SINMessage object is composed of two elements, the message object itself and its direction (incoming or outgoing).

Now that we can send and receive messages, we need to know when a message has finished sending if we are the author so that we can update the data source and reload the table view. To accomplish this, we implement the messageSent:recipientId: as shown below.

We can also implement some of the remaining delegate methods to help us troubleshoot the messaging process if something were to go wrong. Add the following delegate methods below the messageSent:recipientId: method.

At this point, messaging with Sinch is ready to use. The last thing we'll need to do is edit the tableView:cellForRowAtIndexPath: method to display the messages. This is what the implementation should look like:

9. Test Messaging

Build and run the app to ensure that there are no errors. You're ready to test out the messaging feature. To try it out, you'll need access to another Facebook account.

On your iOS device, build and run the app and log in with the first account. On the iOS Simulator, run another instance of the app and log in with the second account. Navigate to each other's profile on each device and tap Message.

Trying Out Messaging Using Sinch

At this point, you can enter a message and press Send. It will arrive on the recipient's device almost instantly. You're finished implementing a working messaging client for your dating app using the Sinch platform.

Sending and Receiving Messages Using Sinch

If the user isn't online, the client will try to send the message, but it won't arrive at the other user. In this case, you may want to implement push notifications to let the recipient know they've received a message.

10. VoIP Calling

The last feature we will utilize Sinch for is VoIP (Voice over IP) calling. Open CallingViewController.m and import the Sinch framework one last time.

Like before, we'll make use of some protocols to handle calling. The SINCallClientDelegate and SINCallDelegate protocols provide us methods to initiate and receive a call, and be updated of the status of a call. Update the interface of the  CallingViewController class to conform it to both protocols.

To implement VoIP calling, we'll need access to the Sinch client as well as a SINCall object. Add a property for the SINCall instance as shown below.

In viewDidLoad, set the view controller as the delegate of the Sinch call client.

To better understand the next section, it helps to go through the scenarios users will face when using the call feature. A user could be:

  • receiving a call
  • making a call
  • hanging up an existing call
  • rejecting an incoming call

Let's address making and receiving a call first. Add the following code to the makeOrAcceptCallFromSelectedUser: method:

We check to see if we're making a call or have one coming in. If we are initiating the call, callUserWithId: will start the calling process and initialize the sinchCall property.

If we are answering a call, the sinchCall property will already be initialized and we simply begin the call by calling answer on it.

Next, we'll implement rejecting and hanging up a call. Add the following code to the rejectOrHangUpCallFromSelectedUser: method:

This code is easier to digest, because, no matter the situation, it's handled by calling hangup on the sinchCall property.

All that's left for us to do is implement the required delegate methods. This will be quite a bit of code, but it's simple to understand and the method names are very descriptive.

The first method, didReceiveIncomingCall:, handles receiving a call and setting up the sinchCall property. We'll also know when the call starts and ends from callDidEstablish: and callDidEnd:.

The last method, callDidProgress:, is empty at the moment, but it would be useful for updating the user interface with helpful information, such as the duration of the call. You could use SINCallDetail and its establishedTime property to easily make that calculation.

11. Test Calling

Run two instances of the app using two Facebook accounts as you did before. Navigate to each other's profile and tap Call.

Hit the green Call button on your device or in the iOS Simulator. Once the call is sent to Sinch, the user interface will update to let the user know the call is in progress.

Setting Up a Call with Sinch

Similarly, if one of the users is receiving a call, the user interface will look like this:

Incoming Call

Finally, when the call is in progress, the user interface will reflect the state of the call. A button labeled Hang Up will be visible to end the call.

A Call in Progress

Similar to messaging, attempting to call a user that isn't online is not supported by the app. As with messaging, you could solve this by using push notifications to notify the user that someone has tried to call you.

12. Where To Go Next

There are several parts of the app that can be improved. The most notable is the integration of push notifications. Sinch recently added native support for push notifications to their iOS SDK, taking the burden off developers. With push notifications, you could notify users that aren't currently using the app that they have received a call or a message.

Another useful addition would be to store messages and conversations on a remote backend. This way, users could go back in time and view past conversations they've had. It also makes the messaging experience more fluid since they could pick up a conversation where they left off.

These are just a few ideas. I'm sure you can think of a few more that would make the app more complete and engaging.

Conclusion

Sinch's powerful SDK makes two intimidating tasks approachable, easy, and affordable. As you've seen in this tutorial, Sinch allows developers to integrate messaging and calling in their apps in a matter of minutes. The Sinch SDK isn't limited to iOS. If your dating app has a website component, for example, then you could use their JavaScript API to implement the same features.

If you got stuck along the way, don't worry, you can find the finished project on GitHub. You can now take what you've learned in this tutorial and go create the next Tinder.

2015-05-01T16:02:18.000Z2015-05-01T16:02:18.000ZJordan Morgan

Creating a Dating Application with Sinch: Integrating Sinch

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

Dating apps have become one of the more popular genres in the App Store recently. Due to their nature, however, developing a fully featured dating app can be challenging. In the second part of this series, we'll look at how we can leverage the Sinch platform in an iOS app to implement voice calls and messaging. These are two cornerstone features for dating apps and they are surprisingly easy to implement with Sinch.

1. Overview

Before we begin coding, let's review the app we are making. Our dating app will have a few core features that we'll focus on in this tutorial. For accounts, users will be able to sign in using Facebook. After signing in, they'll be able to see other users of the app that are nearby.

The users are stored on the server that we communicate with from the restful API created in the first part of this tutorial. Once we get the user's information from Facebook, a new user is posted to the server and a session created. After that, a list of registered users will be retrieved to select from.

When the user finds someone they want to talk to, they will be able to either message them or initiate a voice call. This is where Sinch will come into play. We'll utilize their SDK to do all of the hard work of handling voice calls and messaging.

Now that we know what we are developing, it's time to get started.

2. Starter Project

Start by downloading the starter project from GitHub. The app is targeted at iPhone and it contains the user interface, Facebook authentication, and communication with the RESTful API already in place. This will allow us to focus on integrating with Sinch.

Before we continue, though, I'd like to discuss the basic architecture of the app and how it communicates with the server. The code that communicates with the rest API lives in the UsersAPIClient class. It uses the popular AFNetworking library to simplify the networking logic. If you've used AFNetworking before, this will look very familiar to you. If you haven't, our tutorial about AFNetworking is an excellent place to start.

In the header file, you'll see some methods to communicate with various endpoints of the RESTful API, such as creating a user, starting a session, deleting a user, and more.

When a response comes back from the server, the JSON is parsed and used to initialize a model.

Speaking of models, there is one model used in the project, User. It contains basic information about a user, such as name, location, id, etc. The user id is especially important since we'll need it to uniquely identify who we are communicating with when we integrate with Sinch.

Take a few moments to browse the project to get a better understanding of its structure. Just like with third party libraries, it's tremendously helpful to browse documentation and source code before you actually use it.

3. Build and Run 

If you build and run the demo project, you should be prompted to log in via Facebook.

Log In with Facebook

Go ahead and check if you can log in with Facebook. After logging in, the demo app does three things:

  • It creates a user record on the backend if one isn't present.
  • It starts a user session and creates an access token for the session.
  • It retrieves a list of users in the system.

Later on, when you've made a few test accounts, you can find users within a certain range. By default, every user in the system is returned since it's unlikely any other users are nearby while you're testing.

4. Create a Sinch Account

To use the Sinch SDK, you'll first need to create a developer account. Head over to the Sinch website and click Get Started For Free in the top right to sign up.

Sign Up for a Free Sinch Account

Enter your email address and password, and accept the terms and conditions. Sinch will automatically start a setup process after you sign up. At this point, all you need to do is name your app and add a short description. You can skip the rest of the start guide for now.

Next, visit the dashboard to retrieve your app's API key and secret. You should see Dashboard at the top of Sinch's website after you've signed in with your new account. Select Apps on the left, select the app you created, and click the keys icon on the right to show the key and secret. You'll want to keep track of these values to later initialize the Sinch client.

Finding Your Apps Key and Secret

5. Add Sinch SDK

There are two ways to add the Sinch SDK to your project. The easiest approach by far is through CocoaPods. Add the following line to your Podfile:

Next, run the following command to integrate the Sinch SDK into your workspace:

In this tutorial, however, I'll show you how to add the SDK if you're not using CocoaPods. Start by downloading the Sinch SDK for iOS. Visit the downloads section of the Sinch website and download the SDK for iOS. The Sinch SDK depends on three frameworks so we'll need to link our project against those first. In the Project Navigator, choose SinchTutorial and select the SinceTutorial target.

Select the SinchTutorial Target

 Select Build Phases > Link Binary With Libraries and click the plus button at the bottom.

Add Libraries

Add the following frameworks to the list of frameworks to link with:

  • Security
  • AudioToolbox
  • AVFoundation

We also need to add three linker flags. In the target's Build Settings, search for Other Linker Flags.

Add Other Linker Flags

Add the following linker flags under Debug:

Finally, drag the Sinch framework that you downloaded earlier into the Frameworks folder in the Project Navigator. Build your project to make sure there are no errors. You're now ready to start using the Sinch SDK.

6. Setting Up the Sinch Client

The Sinch client is the driving force responsible for communicating with the Sinch platform. Before we can use the messaging or calling features, we'll need to initialize an instance of the Sinch client. To do this, we need the key and secret that we retrieved earlier after creating our Sinch account.

Open AppDelegate.h and import the Sinch framework as shown below.

Next, we need to create a property for the Sinch client and a method prototype for initializing it. Add the following code snippet below the window property.

We'll use this reference to the Sinch client to easily get calls and messaging going. The SINClientDelegate protocol will inform us whether connecting with the Sinch backend was successful.

Conform the AppDelegate class to the SINClientDelegate protocol as shown below.

Switch to the implementation file of the AppDelegate class and implement the sinchClientWithUserId: method as shown below.

We'll use this method later to communicate with the Sinch backend after the user has logged in. Remember to enter the application key and secret. Otherwise you'll be unable to connect to the Sinch backend.

After initializing the client, we tell Sinch that we'll be using the messaging and calling features. We then start the client and establish a connection with the Sinch services to receive incoming calls.

Next, implement the following delegate methods of the SINClientDelegate protocol in the AppDelegate class:

These delegate methods will log errors to the Xcode console should any occur and they also inform us when we've successfully connected with Sinch.

7. Initializing the Sinch Client

Open FindUsersViewController.m and scroll to the beginUserSession method. In this method, if a session was started without errors the completion block is executed. This is a good time to initialize the Sinch client. Replace the //TODO comment with the following code block:

This calls the method to start the Sinch client and allows us to start using its features. Build and run the app. After you've retrieved a list of users, confirm that connecting with the Sinch backend was successful by checking the logs in the Xcode console.

8.  Implement Messaging

We're now getting to the fun part, adding a messaging component with very little code using the Sinch SDK. Start by opening MessagingViewController.m and import the Sinch framework.

Much like the SINClientDelegate protocol provides helpful methods that help us keep track of the client's status, the SINMessageClientDelegate protocol keeps us informed about incoming and outgoing messages, their status, and more.

Start by conforming the MessagingViewController class to this protocol by updating the interface of the class.

To implement messaging, we'll also need a SINMessageClient instance to handle the responsibilities of messaging. Add a property for the SINMessageClient instance.

We can create an instance of a messaging client from the Sinch client we already have in the app delegate. When the view controller loads, we need to initialize one and set the view controller as its delegate. Add the following code block to the view controller's viewDidLoad method:

Now that we've got an object to send and receive messages, and a delegate to handle them, let's add code to compose a message. Find the sendMessage: method at the bottom of the view controller and add the following implementation:

A SINOutgoingMessage instance will contact Sinch and move the message over to the recipient. We designate the recipient by providing their user id from the user's model. Sinch will know where to go with the message by routing it through their API using a combination of your application key, secret, and the unique user id passed to it.

Since a message could either be incoming or outgoing, add an enum at the top of the view controller to account for either scenario. Add it below the import statements.

Finally, we'll need the messaging client to actually process and send the message. In this view controller, we'll need to handle both sending and receiving messages. Add the following code snippet to receive a message:

Whenever we receive a message, we'll add it to the messages array and reload the table view to display it. It's important to note that the SINMessage object is composed of two elements, the message object itself and its direction (incoming or outgoing).

Now that we can send and receive messages, we need to know when a message has finished sending if we are the author so that we can update the data source and reload the table view. To accomplish this, we implement the messageSent:recipientId: as shown below.

We can also implement some of the remaining delegate methods to help us troubleshoot the messaging process if something were to go wrong. Add the following delegate methods below the messageSent:recipientId: method.

At this point, messaging with Sinch is ready to use. The last thing we'll need to do is edit the tableView:cellForRowAtIndexPath: method to display the messages. This is what the implementation should look like:

9. Test Messaging

Build and run the app to ensure that there are no errors. You're ready to test out the messaging feature. To try it out, you'll need access to another Facebook account.

On your iOS device, build and run the app and log in with the first account. On the iOS Simulator, run another instance of the app and log in with the second account. Navigate to each other's profile on each device and tap Message.

Trying Out Messaging Using Sinch

At this point, you can enter a message and press Send. It will arrive on the recipient's device almost instantly. You're finished implementing a working messaging client for your dating app using the Sinch platform.

Sending and Receiving Messages Using Sinch

If the user isn't online, the client will try to send the message, but it won't arrive at the other user. In this case, you may want to implement push notifications to let the recipient know they've received a message.

10. VoIP Calling

The last feature we will utilize Sinch for is VoIP (Voice over IP) calling. Open CallingViewController.m and import the Sinch framework one last time.

Like before, we'll make use of some protocols to handle calling. The SINCallClientDelegate and SINCallDelegate protocols provide us methods to initiate and receive a call, and be updated of the status of a call. Update the interface of the  CallingViewController class to conform it to both protocols.

To implement VoIP calling, we'll need access to the Sinch client as well as a SINCall object. Add a property for the SINCall instance as shown below.

In viewDidLoad, set the view controller as the delegate of the Sinch call client.

To better understand the next section, it helps to go through the scenarios users will face when using the call feature. A user could be:

  • receiving a call
  • making a call
  • hanging up an existing call
  • rejecting an incoming call

Let's address making and receiving a call first. Add the following code to the makeOrAcceptCallFromSelectedUser: method:

We check to see if we're making a call or have one coming in. If we are initiating the call, callUserWithId: will start the calling process and initialize the sinchCall property.

If we are answering a call, the sinchCall property will already be initialized and we simply begin the call by calling answer on it.

Next, we'll implement rejecting and hanging up a call. Add the following code to the rejectOrHangUpCallFromSelectedUser: method:

This code is easier to digest, because, no matter the situation, it's handled by calling hangup on the sinchCall property.

All that's left for us to do is implement the required delegate methods. This will be quite a bit of code, but it's simple to understand and the method names are very descriptive.

The first method, didReceiveIncomingCall:, handles receiving a call and setting up the sinchCall property. We'll also know when the call starts and ends from callDidEstablish: and callDidEnd:.

The last method, callDidProgress:, is empty at the moment, but it would be useful for updating the user interface with helpful information, such as the duration of the call. You could use SINCallDetail and its establishedTime property to easily make that calculation.

11. Test Calling

Run two instances of the app using two Facebook accounts as you did before. Navigate to each other's profile and tap Call.

Hit the green Call button on your device or in the iOS Simulator. Once the call is sent to Sinch, the user interface will update to let the user know the call is in progress.

Setting Up a Call with Sinch

Similarly, if one of the users is receiving a call, the user interface will look like this:

Incoming Call

Finally, when the call is in progress, the user interface will reflect the state of the call. A button labeled Hang Up will be visible to end the call.

A Call in Progress

Similar to messaging, attempting to call a user that isn't online is not supported by the app. As with messaging, you could solve this by using push notifications to notify the user that someone has tried to call you.

12. Where To Go Next

There are several parts of the app that can be improved. The most notable is the integration of push notifications. Sinch recently added native support for push notifications to their iOS SDK, taking the burden off developers. With push notifications, you could notify users that aren't currently using the app that they have received a call or a message.

Another useful addition would be to store messages and conversations on a remote backend. This way, users could go back in time and view past conversations they've had. It also makes the messaging experience more fluid since they could pick up a conversation where they left off.

These are just a few ideas. I'm sure you can think of a few more that would make the app more complete and engaging.

Conclusion

Sinch's powerful SDK makes two intimidating tasks approachable, easy, and affordable. As you've seen in this tutorial, Sinch allows developers to integrate messaging and calling in their apps in a matter of minutes. The Sinch SDK isn't limited to iOS. If your dating app has a website component, for example, then you could use their JavaScript API to implement the same features.

If you got stuck along the way, don't worry, you can find the finished project on GitHub. You can now take what you've learned in this tutorial and go create the next Tinder.

2015-05-01T16:02:18.000Z2015-05-01T16:02:18.000ZJordan Morgan

Quick Tip: Authentication with Twitter and Fabric

$
0
0

Users who have just downloaded your Android app are going to be a lot happier if you allow them to log in using a popular social networking service instead of asking them to fill out a registration form. In this quick tip, you are going to learn how to enable your users to sign into your app with their Twitter accounts.

Prerequisites

To follow along, you should have the following set up:

Fabric is Twitter's framework for developing mobile applications. It provides a set of tools to make mobile development easier and more streamlined. It includes crash reporting, beta distribution, mobile analytics, etc. If you don't have a Fabric account yet, you will have to request an invite and wait for a day or two.

1. Register Your App

Any app that needs to interact with Twitter's APIs should be registered using the Twitter Application Management console. Use your Twitter account to log in.

Click on the Create New App button, and fill out the form. Enter meaningful values in the Name and Description fields, because these will be shown to your app's users. We won't be needing the Website and Callback URL for this tutorial, but you can't leave them blank. If you have your own website, you can use its address here. If you don't,  you can simply type in http://example.com.

Create an Application

Accept the agreement and submit the form. Your app is now registered.

Click on the Keys and Access Tokens tab and make note of your Consumer Key and Consumer Secret. We'll be needing them later.

Make Note of the Consumer Key and Consumer Secret

2. Install Fabric for Android Studio

Log in to your Fabric account and download the plugin for Android Studio.

Download Fabric for Android Studio

Once the download completes, start Android Studio and select Configure > Plugins.

Install Fabric for Android Studio

Click on the Install plugin from disk button and select the file you just downloaded. Once installed, you should be able to see Fabric for Android Studio in the list of plugins.

Install Fabric for Android Studio

3. Use the Fabric Plugin

Create a new project (or open an existing one) and click on the Fabric icon. Log in to your Fabric account and select Twitter to install Twitter Kit for your project.

Select Twitter Kit

As we will be using Twitter Kit only to log into Twitter, choose Log in with Twitter in the next screen.

Were Only Interested in Log In with Twitter

Finally, you will be shown the code changes you need to make in your project. First, you will see the changes you need to make in the build.grade file. You can simply copy and paste these changes.

Update the buildgradle File

Next, when you choose the tab for AndroidManifest.xml, you will see that two additions need to be made:

  • To interact with Twitter's servers, the android.permission.INTERNET permission must be requested.
  • The automatically generated API key should be mentioned in the form of meta-data. Again, you can simply copy and paste the code shown by the plugin.

You will see that a new file named fabric.properties has been created in your app directory. Open the file, and add the same API key to it as shown below.

4. Create an Activity

In this tutorial, we will be creating a very simple Activity that displays a login button and a TextView that displays the result of the login attempt.

Step 1: Define the Layout

Create a new layout XML called login_activity.xml in the res/layout directory. Add a TwitterLoginButton using the following code snippet:

Next, add a TextView to display the results of the login attempt.

Step 2: Create the Class

Create a new Java class that extends the Activity class and override its onCreate method. Use setContentView to use the layout XML we created in the previous step.

Retrieve the widgets defined in the XML using the findViewById method. You can leave the TextView blank, but I am going to use the setText method and display a String that says "Status: Ready".

At this point, your class should have the following code in it:

When you click the plugin icon again and click on the tab for Start Activity, you will find the code that needs to be added to initialize Fabric. Copy and paste that code in the onCreate method, before the call to setContentView.

The plugin generates its own values for consumer key and consumer secret. While you can use these values, we will be using the values we got when we registered our application in Twitter's Application Management console earlier. The code to use these values should look like this:

Clicking the login button starts an external Activity that returns a result. To capture that result, override the onActivityResult method of the Activity and pass the arguments received to the onActivityResult method of the button:

To process the result of the login attempt, you must create a custom Callback. Create an internal class named LoginHandler that extends Callback<TwitterSession>, and override all its abstract methods.

The names of the methods of this class are very intuitive. In case of a successful login, the success method is called. Otherwise, the failure method is called.

For the TwitterLoginButton to use this custom callback, in the onCreate method of the Activity, pass an instance of LoginHandler to the button's setCallback method.

In case of a successful login attempt, display the name of the logged in user and the auth token. Both values are available from the data field of Result<TwitterSession>. To get the username of the logged in user use getUsername. Similarly, to get the auth token use getAuthToken. Add the following code to the success method:

In case of a failed login attempt, display a message that says "Login Failed". Add the following to the failure method:

Step 3: Update the Manifest

Define the Activity you just created in your project's manifest. If it is your app's first Activity, create an intent filter so that it responds to android.intent.action.MAIN. Add the following code to your file:

5. Build and Run

Your app is now ready to be run. When you build and run it on your Android device, you will be greeted with the following screen:

If you tap the login button, you will be redirected to Twitter. Note that the application name and description you specified in the first step of this tutorial are shown on this page.

When you tap the Authorize app button, the login attempt is considered successful and you are redirected back to your app. You will see that the TextView is updated to show the username and the auth token.

Conclusion

In this quick tip, you have learned how to enable your app's users to log in using Twitter. You also learned how to install the Fabric plugin for Android Studio and how to use it to add Twitter Kit to your project. To learn more about Fabric and Twitter Kit, refer to the Twitter Kit for Android documentation.

2015-05-04T17:15:12.000Z2015-05-04T17:15:12.000ZAshraff Hathibelagal

Quick Tip: Authentication with Twitter and Fabric

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

Users who have just downloaded your Android app are going to be a lot happier if you allow them to log in using a popular social networking service instead of asking them to fill out a registration form. In this quick tip, you are going to learn how to enable your users to sign into your app with their Twitter accounts.

Prerequisites

To follow along, you should have the following set up:

Fabric is Twitter's framework for developing mobile applications. It provides a set of tools to make mobile development easier and more streamlined. It includes crash reporting, beta distribution, mobile analytics, etc. If you don't have a Fabric account yet, you will have to request an invite and wait for a day or two.

1. Register Your App

Any app that needs to interact with Twitter's APIs should be registered using the Twitter Application Management console. Use your Twitter account to log in.

Click on the Create New App button, and fill out the form. Enter meaningful values in the Name and Description fields, because these will be shown to your app's users. We won't be needing the Website and Callback URL for this tutorial, but you can't leave them blank. If you have your own website, you can use its address here. If you don't,  you can simply type in http://example.com.

Create an Application

Accept the agreement and submit the form. Your app is now registered.

Click on the Keys and Access Tokens tab and make note of your Consumer Key and Consumer Secret. We'll be needing them later.

Make Note of the Consumer Key and Consumer Secret

2. Install Fabric for Android Studio

Log in to your Fabric account and download the plugin for Android Studio.

Download Fabric for Android Studio

Once the download completes, start Android Studio and select Configure > Plugins.

Install Fabric for Android Studio

Click on the Install plugin from disk button and select the file you just downloaded. Once installed, you should be able to see Fabric for Android Studio in the list of plugins.

Install Fabric for Android Studio

3. Use the Fabric Plugin

Create a new project (or open an existing one) and click on the Fabric icon. Log in to your Fabric account and select Twitter to install Twitter Kit for your project.

Select Twitter Kit

As we will be using Twitter Kit only to log into Twitter, choose Log in with Twitter in the next screen.

Were Only Interested in Log In with Twitter

Finally, you will be shown the code changes you need to make in your project. First, you will see the changes you need to make in the build.grade file. You can simply copy and paste these changes.

Update the buildgradle File

Next, when you choose the tab for AndroidManifest.xml, you will see that two additions need to be made:

  • To interact with Twitter's servers, the android.permission.INTERNET permission must be requested.
  • The automatically generated API key should be mentioned in the form of meta-data. Again, you can simply copy and paste the code shown by the plugin.

You will see that a new file named fabric.properties has been created in your app directory. Open the file, and add the same API key to it as shown below.

4. Create an Activity

In this tutorial, we will be creating a very simple Activity that displays a login button and a TextView that displays the result of the login attempt.

Step 1: Define the Layout

Create a new layout XML called login_activity.xml in the res/layout directory. Add a TwitterLoginButton using the following code snippet:

Next, add a TextView to display the results of the login attempt.

Step 2: Create the Class

Create a new Java class that extends the Activity class and override its onCreate method. Use setContentView to use the layout XML we created in the previous step.

Retrieve the widgets defined in the XML using the findViewById method. You can leave the TextView blank, but I am going to use the setText method and display a String that says "Status: Ready".

At this point, your class should have the following code in it:

When you click the plugin icon again and click on the tab for Start Activity, you will find the code that needs to be added to initialize Fabric. Copy and paste that code in the onCreate method, before the call to setContentView.

The plugin generates its own values for consumer key and consumer secret. While you can use these values, we will be using the values we got when we registered our application in Twitter's Application Management console earlier. The code to use these values should look like this:

Clicking the login button starts an external Activity that returns a result. To capture that result, override the onActivityResult method of the Activity and pass the arguments received to the onActivityResult method of the button:

To process the result of the login attempt, you must create a custom Callback. Create an internal class named LoginHandler that extends Callback<TwitterSession>, and override all its abstract methods.

The names of the methods of this class are very intuitive. In case of a successful login, the success method is called. Otherwise, the failure method is called.

For the TwitterLoginButton to use this custom callback, in the onCreate method of the Activity, pass an instance of LoginHandler to the button's setCallback method.

In case of a successful login attempt, display the name of the logged in user and the auth token. Both values are available from the data field of Result<TwitterSession>. To get the username of the logged in user use getUsername. Similarly, to get the auth token use getAuthToken. Add the following code to the success method:

In case of a failed login attempt, display a message that says "Login Failed". Add the following to the failure method:

Step 3: Update the Manifest

Define the Activity you just created in your project's manifest. If it is your app's first Activity, create an intent filter so that it responds to android.intent.action.MAIN. Add the following code to your file:

5. Build and Run

Your app is now ready to be run. When you build and run it on your Android device, you will be greeted with the following screen:

If you tap the login button, you will be redirected to Twitter. Note that the application name and description you specified in the first step of this tutorial are shown on this page.

When you tap the Authorize app button, the login attempt is considered successful and you are redirected back to your app. You will see that the TextView is updated to show the username and the auth token.

Conclusion

In this quick tip, you have learned how to enable your app's users to log in using Twitter. You also learned how to install the Fabric plugin for Android Studio and how to use it to add Twitter Kit to your project. To learn more about Fabric and Twitter Kit, refer to the Twitter Kit for Android documentation.

2015-05-04T17:15:12.000Z2015-05-04T17:15:12.000ZAshraff Hathibelagal

Adding Authentication Using Azure Mobile Services

$
0
0

Azure Mobile Services let you authenticate users from your universal Windows apps. In this tutorial, you will learn how to:

  • add authentication to a Windows Phone 8.1 WinRT app using different identity providers supported by Azure Mobile Services
  • store cached authentication tokens on the client
  • retrieve and store user profile details in an Azure database using server scripts
  • add additional authentication scopes to retrieve more user information from the server
  • edit the insert script of the UsersTable to insert a record if a user with the same userId doesn't exist, and otherwise update the existing user

The following steps are required to enable authentication in your app:

  • register your app for authentication
  • configure Azure Mobile Services
  • restrict table permissions to authenticated users
  • configure your app to use Azure Mobile Services
  • add authentication to the app
  • cache authentication tokens on the client
  • retrieve user information from the server

You must register your app with an identity provider and add the provider generated credentials to Azure Mobile Services. Let us first see how to register your app for Microsoft account login. 

1. App Registration

To use Live Connect as an authentication provider for Azure Mobile Services, follow these steps.

Step 1: Create a New App in the Dev Center

Open a browser and head over to the Dev Center for Windows Store apps. Navigate to the Submit an app page and click App Name.

Submit an app to Windows Store

Step 2: Reserve an App Name

Reserve an App name and click Save. The app will be listed in the Windows Store under this name.

Reserve app name

Step 3: Configure Live Services for the App

On the Services page, click Live Services under Windows Azure Mobile Services.

Navigate to Live Services site

Step 4: Note the App Settings Values

Note the values of Client ID, Client secret, and Package security identifier (SID). You will need these values later.

Note the App Settings from Live Services site

Step 5: Set the Redirect URI for the App

Under API Settings, supply the following value as Redirect URl and click Save.

Configure App Settings in Live Services Site

This enables Microsoft account authentication for your app.

2. Configure Azure Mobile Services

Once you have registered your app with the identity provider, you need to configure Azure Mobile Services using the Azure Management Portal.

Step 1: Select the Mobile Service for the App 

Log in to the Azure Management Portal, click Mobile Services, and select your app.

Select Mobile Service in Azure Management Portal

Step 2: Configure Push Settings

Under the Push tab, enter the Client Secret and Package SID values, and click Save.

Set Client Secret and Package SID for the app

Step 3: Configure Identity Settings

Under the Identity tab, set the Client ID. Also set the Client Secret and Package SID values if they are not already set.

Configure Microsoft account settings

You are now ready to use a Microsoft account for authentication in your app using Azure Mobile Services.

3. Restrict Table Permissions

Using the Azure Management Portal, we can set the table permissions to restrict access only to logged in users.

Step 1: Select the UsersTable

Under the Data tab in the Azure Management Portal, choose the table for which you'd like to change the permissions. In this tutorial, we are modifying permissions for UsersTable.

Step 2: Set Table Permissions

Under the Permissions tab, set all permissions to Only authenticated users and click Save.

Restrict table permissions to authenticated users

When your Windows Store app tries to access this table, an unhandled exception with a status code of 401 (Unauthorized) is raised. This happens because the app attempts to access Azure Mobile Services as an unauthenticated user.

4. Configure the App to Use Mobile Services

Next, we need to configure the Windows Phone 8.1 WinRT app to use Azure Mobile Services.

Step 1: (Optional) Associate Your App With the Store

This step applies only to the Microsoft account login provider. On registering the Windows Store app package information with Mobile Services, the client is able to reuse Microsoft login details for a single sign-on experience. 

Right-click the project in the Solution Explorer, select Store and click Associate App with the Store. In the Associate Your App with the Windows Store wizard, click Sign in and log in with your Microsoft account. Select the app that you registered earlier and Associate it with the store.

Associate app with store

The required Windows Store registration information is then added to the application manifest.

Step 2: Add Windows Azure Mobile Services SDK

Next, add the Windows Azure Mobile Services SDK using the NuGet package manager.

Add Windows Azure Mobile Services SDK to the app

Step 3: Add Azure Mobile Services as a Connected Service

The mobile service you created in the Azure Management Portal needs to be linked with the app. Right-click the project in the Solution Explorer and select Connected Services under Add.

In the Service Manager dialog box that appears, choose the mobile service that you created earlier and click OK. This adds an instance of mobile service in App.xaml.cs.

Connect the Mobile Service with your app

Step 4: Add a Class for UsersTable

Define a class UsersTable whose data members represent the columns in the table. You will need to add a reference to the Json.NET library in your app to use the JsonProperty class.

5. Add Authentication to the App

Next, we will add user authentication before we request any resources from the mobile service.

Step 1: Declare Global Variables

Declare a member variable global to the MainPage class for storing the authenticated user.

Step 2: Define the AuthenticateAsync Method

We add a method that performs the authentication process. The LoginAsync method takes the identity provider as a parameter and handles the authentication flow.

Step 3: Handle the Response on App Activation

On Windows Phone 8.1, you need to handle the response from the WebAuthenticationBroker. We add an OnActivated method in App.xaml.cs to handle this response.

If the OnActivated method already exists, just add the above #if...#endif code block. Note that the LoginAsync method must be called after the OnNavigated method has been called and after the page's Loaded event has been triggered.

Step 4: Add a Login Button

Add a login button to your app's MainPage.xaml and call a method to authenticate the user when the button is clicked.

On button click, call the AuthenticateAsync method and hide the login button if the authentication is successful.

Step 5: Handle Exceptions in the AuthenticateAsync Method

Our AuthenticateAsync method handles authentication of users, but we can add code to handle exceptions and alternate flows. We update the function to iteratively call the LoginAsync method until the user is not null. On successful authentication, we display the UserId of the authenticated user. Once the user is successfully logged in, the app should run without errors.

6. Cache Authentication Tokens on the Client

The AuthenticateAsync function requires the client to contact both the identity provider and the mobile service every time the app starts. That is not very efficient. Also, if many users use the app at the same time, you may run into load issues.

To remedy this issue, we can cache the authentication token. We can try to use the cached authentication token, falling back to the default authentication flow if the authentication token is no longer valid.

The modified AuthenticateAsync function tries to use the credentials stored in the PasswordVault to access the mobile service. The following sequence of events occurs:

  • If credentials are present, they are fetched from the PasswordVault.
  • A simple query is sent to verify that the token hasn't expired.
  • If the server responds with a 401 status code, then we fall back to the default authentication flow.
  • If the PasswordVault doesn't contain a credentials, we fall back to the default authentication flow.

Note that the app tests for expired authentication tokens during login. However, authentication tokens can expire after authentication, when the user is using the app. An MSDN blog post explains how to handle such a situation.

7. Fetch User Information

The client objects don't expose all the user information, but on the server we can get all the information we need. The User object, which is passed to all scripts, has a getIdentities function that returns an object with provider-specific data. It can be used to query the user information. For a user authenticated with a Microsoft account, the object is returned by calling user.getIdentities.

To get the user information, we send a request to https://apis.live.net/v5.0/me/, passing the access token as a parameter. The amount of information available from the providers to the user scripts is limited. This is the result of the request to the /me endpoint:

 Additional authentication scopes need to be requested for more information. Azure Mobile Services allow us to specify custom scopes that are passed to the authentication providers when performing server-side authentication.

By default, the login only requests the wl.basic scope. We can get more information about the user if we set some additional scopes. Let's now request an additional scope from the Microsoft login.

Under the Configure tab of the mobile service, set the MS_MicrosoftScope in app settings.

app settings

As a result of this change, I will get the additional information I requested after logging in again.

If the user is logged in via a Microsoft account, it will send a request to Live Connect APIs, passing the stored token in the user identities object. Finally, it will parse the JSON object that is returned and retrieve user profile details.

We now need to modify the insert script to insert a new record if a user with the userId doesn't exist. If a user exists, we update that user. You can use a server-side table script to check if a record exists before completing the insert operation.

Here is an example script that checks if any of the items in the table has a matching userId value and, if that is the case, it doesn’t perform an insert.

We can now combine both scripts to construct our final insert script for UsersTable. Under the Script tab of UsersTable, replace the insert script with the following script:

Now that we have updated the insert script, any call for an insert operation will add a new record if a user with a specific userId doesn't exist. Also, the insert item is updated with user information userId, name, and email.

I have added a method InsertUser, which takes a parameter user of type UsersTable and inserts it into the table.

After the call to the AuthenticateAsync method on button click, I call the InsertUser method to add the user to UsersTable.

You can run the app in the emulator to see if it works. When you log in for the second time, the app uses the cached authentication token instead of presenting the login screen.

Login using a Microsoft account

Conclusion

Authenticating users for different identity providers using Azure Mobile Services is quite simple. In this tutorial, I showed how a Microsoft account can be used for authentication. The procedure to use other identity providers is the same. Only the provider parameter needs to be changed in the AuthenticateAsync call. It's recommended to cache the authentication token so that the user can experience single sign-on.

Additional authentication scopes can be requested to fetch more user information. This MSDN article discusses how it can be done for various identity providers. Feel free to download the tutorial's source files for reference. Remember to configure the app to use Azure Mobile Services before deploying it.

2015-05-06T16:15:07.000Z2015-05-06T16:15:07.000ZVivek Maskara

Adding Authentication Using Azure Mobile Services

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

Azure Mobile Services let you authenticate users from your universal Windows apps. In this tutorial, you will learn how to:

  • add authentication to a Windows Phone 8.1 WinRT app using different identity providers supported by Azure Mobile Services
  • store cached authentication tokens on the client
  • retrieve and store user profile details in an Azure database using server scripts
  • add additional authentication scopes to retrieve more user information from the server
  • edit the insert script of the UsersTable to insert a record if a user with the same userId doesn't exist, and otherwise update the existing user

The following steps are required to enable authentication in your app:

  • register your app for authentication
  • configure Azure Mobile Services
  • restrict table permissions to authenticated users
  • configure your app to use Azure Mobile Services
  • add authentication to the app
  • cache authentication tokens on the client
  • retrieve user information from the server

You must register your app with an identity provider and add the provider generated credentials to Azure Mobile Services. Let us first see how to register your app for Microsoft account login. 

1. App Registration

To use Live Connect as an authentication provider for Azure Mobile Services, follow these steps.

Step 1: Create a New App in the Dev Center

Open a browser and head over to the Dev Center for Windows Store apps. Navigate to the Submit an app page and click App Name.

Submit an app to Windows Store

Step 2: Reserve an App Name

Reserve an App name and click Save. The app will be listed in the Windows Store under this name.

Reserve app name

Step 3: Configure Live Services for the App

On the Services page, click Live Services under Windows Azure Mobile Services.

Navigate to Live Services site

Step 4: Note the App Settings Values

Note the values of Client ID, Client secret, and Package security identifier (SID). You will need these values later.

Note the App Settings from Live Services site

Step 5: Set the Redirect URI for the App

Under API Settings, supply the following value as Redirect URl and click Save.

Configure App Settings in Live Services Site

This enables Microsoft account authentication for your app.

2. Configure Azure Mobile Services

Once you have registered your app with the identity provider, you need to configure Azure Mobile Services using the Azure Management Portal.

Step 1: Select the Mobile Service for the App 

Log in to the Azure Management Portal, click Mobile Services, and select your app.

Select Mobile Service in Azure Management Portal

Step 2: Configure Push Settings

Under the Push tab, enter the Client Secret and Package SID values, and click Save.

Set Client Secret and Package SID for the app

Step 3: Configure Identity Settings

Under the Identity tab, set the Client ID. Also set the Client Secret and Package SID values if they are not already set.

Configure Microsoft account settings

You are now ready to use a Microsoft account for authentication in your app using Azure Mobile Services.

3. Restrict Table Permissions

Using the Azure Management Portal, we can set the table permissions to restrict access only to logged in users.

Step 1: Select the UsersTable

Under the Data tab in the Azure Management Portal, choose the table for which you'd like to change the permissions. In this tutorial, we are modifying permissions for UsersTable.

Step 2: Set Table Permissions

Under the Permissions tab, set all permissions to Only authenticated users and click Save.

Restrict table permissions to authenticated users

When your Windows Store app tries to access this table, an unhandled exception with a status code of 401 (Unauthorized) is raised. This happens because the app attempts to access Azure Mobile Services as an unauthenticated user.

4. Configure the App to Use Mobile Services

Next, we need to configure the Windows Phone 8.1 WinRT app to use Azure Mobile Services.

Step 1: (Optional) Associate Your App With the Store

This step applies only to the Microsoft account login provider. On registering the Windows Store app package information with Mobile Services, the client is able to reuse Microsoft login details for a single sign-on experience. 

Right-click the project in the Solution Explorer, select Store and click Associate App with the Store. In the Associate Your App with the Windows Store wizard, click Sign in and log in with your Microsoft account. Select the app that you registered earlier and Associate it with the store.

Associate app with store

The required Windows Store registration information is then added to the application manifest.

Step 2: Add Windows Azure Mobile Services SDK

Next, add the Windows Azure Mobile Services SDK using the NuGet package manager.

Add Windows Azure Mobile Services SDK to the app

Step 3: Add Azure Mobile Services as a Connected Service

The mobile service you created in the Azure Management Portal needs to be linked with the app. Right-click the project in the Solution Explorer and select Connected Services under Add.

In the Service Manager dialog box that appears, choose the mobile service that you created earlier and click OK. This adds an instance of mobile service in App.xaml.cs.

Connect the Mobile Service with your app

Step 4: Add a Class for UsersTable

Define a class UsersTable whose data members represent the columns in the table. You will need to add a reference to the Json.NET library in your app to use the JsonProperty class.

5. Add Authentication to the App

Next, we will add user authentication before we request any resources from the mobile service.

Step 1: Declare Global Variables

Declare a member variable global to the MainPage class for storing the authenticated user.

Step 2: Define the AuthenticateAsync Method

We add a method that performs the authentication process. The LoginAsync method takes the identity provider as a parameter and handles the authentication flow.

Step 3: Handle the Response on App Activation

On Windows Phone 8.1, you need to handle the response from the WebAuthenticationBroker. We add an OnActivated method in App.xaml.cs to handle this response.

If the OnActivated method already exists, just add the above #if...#endif code block. Note that the LoginAsync method must be called after the OnNavigated method has been called and after the page's Loaded event has been triggered.

Step 4: Add a Login Button

Add a login button to your app's MainPage.xaml and call a method to authenticate the user when the button is clicked.

On button click, call the AuthenticateAsync method and hide the login button if the authentication is successful.

Step 5: Handle Exceptions in the AuthenticateAsync Method

Our AuthenticateAsync method handles authentication of users, but we can add code to handle exceptions and alternate flows. We update the function to iteratively call the LoginAsync method until the user is not null. On successful authentication, we display the UserId of the authenticated user. Once the user is successfully logged in, the app should run without errors.

6. Cache Authentication Tokens on the Client

The AuthenticateAsync function requires the client to contact both the identity provider and the mobile service every time the app starts. That is not very efficient. Also, if many users use the app at the same time, you may run into load issues.

To remedy this issue, we can cache the authentication token. We can try to use the cached authentication token, falling back to the default authentication flow if the authentication token is no longer valid.

The modified AuthenticateAsync function tries to use the credentials stored in the PasswordVault to access the mobile service. The following sequence of events occurs:

  • If credentials are present, they are fetched from the PasswordVault.
  • A simple query is sent to verify that the token hasn't expired.
  • If the server responds with a 401 status code, then we fall back to the default authentication flow.
  • If the PasswordVault doesn't contain a credentials, we fall back to the default authentication flow.

Note that the app tests for expired authentication tokens during login. However, authentication tokens can expire after authentication, when the user is using the app. An MSDN blog post explains how to handle such a situation.

7. Fetch User Information

The client objects don't expose all the user information, but on the server we can get all the information we need. The User object, which is passed to all scripts, has a getIdentities function that returns an object with provider-specific data. It can be used to query the user information. For a user authenticated with a Microsoft account, the object is returned by calling user.getIdentities.

To get the user information, we send a request to https://apis.live.net/v5.0/me/, passing the access token as a parameter. The amount of information available from the providers to the user scripts is limited. This is the result of the request to the /me endpoint:

 Additional authentication scopes need to be requested for more information. Azure Mobile Services allow us to specify custom scopes that are passed to the authentication providers when performing server-side authentication.

By default, the login only requests the wl.basic scope. We can get more information about the user if we set some additional scopes. Let's now request an additional scope from the Microsoft login.

Under the Configure tab of the mobile service, set the MS_MicrosoftScope in app settings.

app settings

As a result of this change, I will get the additional information I requested after logging in again.

If the user is logged in via a Microsoft account, it will send a request to Live Connect APIs, passing the stored token in the user identities object. Finally, it will parse the JSON object that is returned and retrieve user profile details.

We now need to modify the insert script to insert a new record if a user with the userId doesn't exist. If a user exists, we update that user. You can use a server-side table script to check if a record exists before completing the insert operation.

Here is an example script that checks if any of the items in the table has a matching userId value and, if that is the case, it doesn’t perform an insert.

We can now combine both scripts to construct our final insert script for UsersTable. Under the Script tab of UsersTable, replace the insert script with the following script:

Now that we have updated the insert script, any call for an insert operation will add a new record if a user with a specific userId doesn't exist. Also, the insert item is updated with user information userId, name, and email.

I have added a method InsertUser, which takes a parameter user of type UsersTable and inserts it into the table.

After the call to the AuthenticateAsync method on button click, I call the InsertUser method to add the user to UsersTable.

You can run the app in the emulator to see if it works. When you log in for the second time, the app uses the cached authentication token instead of presenting the login screen.

Login using a Microsoft account

Conclusion

Authenticating users for different identity providers using Azure Mobile Services is quite simple. In this tutorial, I showed how a Microsoft account can be used for authentication. The procedure to use other identity providers is the same. Only the provider parameter needs to be changed in the AuthenticateAsync call. It's recommended to cache the authentication token so that the user can experience single sign-on.

Additional authentication scopes can be requested to fetch more user information. This MSDN article discusses how it can be done for various identity providers. Feel free to download the tutorial's source files for reference. Remember to configure the app to use Azure Mobile Services before deploying it.

2015-05-06T16:15:07.000Z2015-05-06T16:15:07.000ZVivek Maskara

An Introduction to SceneKit: Fundamentals

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

In this tutorial, you will learn how to create a basic 3D scene in SceneKit without the complexities of OpenGL. This includes basic geometry, cameras, lights, materials, and shadows.

Introduction

The SceneKit framework was first launched by Apple alongside OS X 10.8 Mountain Lion and was later made available on iOS with the release of iOS 8. The purpose of this framework is to allow developers to easily integrate 3D graphics into games and applications without the complexities of graphics APIs, such as OpenGL and Metal.

SceneKit allows you to simply provide a description of the assets you want in your scene, with the framework itself handling all of the OpenGL rendering code for you. In this first tutorial, I will teach you some of the fundamentals of working with 3D assets and the basics of the SceneKit framework.

This tutorial requires that you are running at Xcode 6 or higher. While not necessary, I recommend using a physical device running iOS 8 to test your SceneKit code on. You can use the iOS Simulator, but the performance isn't great if your scene becomes more complex. Note that testing on a physical iOS device requires that you have a registered iOS developer account.

1. Fundamentals

The first thing you need to know about SceneKit is that assets, represented by nodes, are arranged in a hierarchical tree called a scene graph. If you are familiar with iOS development, this tree works much like a regular view hierarchy in UIKit. Every scene you create has a single root node that you add subsequent nodes onto and that also provides a basis for the 3D coordinate system of that scene.

When you add a node to a scene, its position is specified by a set of three numbers, a three-component vector represented by the SCNVector3 structure in your code. Each of these three components defines the node's position on the x, y, and z axes as shown in the below image.

3D Coordinates Diagram
Image Credit: Apple SceneKit Framework Reference

Your scene's root node position is defined as (0, 0, 0). In the above image, this is the position where the three axes intersect. The included camera in the image represents the default direction a camera points in when it is added to your scene.

Now that you know some of the basics of how objects are represented by SceneKit, you are ready to begin writing some code.

2. Project Setup

Open Xcode and create a new iOS Application based on the Single View Application template. While you could easily create an application from the Game template using SceneKit, for this tutorial I am going to show you how to start working with SceneKit from scratch.

Choose application template

Enter a Product Name, set Language to Swift, and Devices to Universal. Click Next to continue.

App details

After creating your project, navigate to ViewController.swift and add the following import statement at the top to import the SceneKit framework:

Next, add the following implementation of the viewDidLoad method in the ViewController class:

In the viewDidLoad method, we create a SCNView object, passing in the frame of the view controller's view. We assign the SCNView instance to a constant, sceneView, and add it as a subview of the view controller's view.

The SCNView class is a subclass of UIView and provides an outlet for your SceneKit content. Aside from having the functionality of a regular view, an SCNView also has several properties and methods relating to the SceneKit content.

To check that everything is functioning correctly, build and run your app. You will see that you just have a blank white view.

Initial app view

3. Scene Setup

To render content in an SCNView, you first need to create an SCNScene and assign it to the view. In this scene, you then need to add a camera and at least one light. For this example, you are also going to add a cube for SceneKit to render. Add the following code to the viewDidLoad method:

Let's go through the viewDidLoad method step by step:

  • You first create the scene for your view by invoking the init method. Unless you are loading a prepared scene from an external file, this is the initializer you will always use.
  • Next, you create an SCNCamera object and an SCNNode instance for the camera. You then assign the SCNCamera object to the camera property of cameraNode and move this node along the z axis to see the cube you will create a bit later.
  • In the next step, you create an SCNLight object and a SCNNode named lightNode. The SCNLight instance is assigned to the light property of the light node. The type property of the SCNLight is set to SCNLightTypeOmni. This light type distributes light evenly in all directions from a point in 3D space. You can think of this light type as a regular light bulb.
  • Finally, you create a cube by using the SCNBox class, making the width, height, and length all the same size. The SCNBox class is a subclass of SCNGeometry and is one of the primitive shapes you can create. Other shapes include spheres, pyramids, and toruses. You also create a node passing in the cube for the geometry parameter.
  • To set the scene up, you add the three nodes (camera, light, and cube) to the scene's scene graph. Additional setup isn't necessary as an SCNScene object automatically detects when a node contains a camera or light object, rendering the scene accordingly.

Build and run your app, and you will see that you now have a black cube being illuminated by your light from the top-right corner.

First SceneKit render

Unfortunately, the cube doesn't look three-dimensional at the moment. This is because the camera is positioned directly in front of it. What you are going to do now is change the position of the camera so that it has a better view of the cube.

To keep the camera pointed directly at the cube, however, you are also going to add an SCNLookAtConstraint to the camera. Start by updating the position of the camera as shown below.

Next, add the following code snippet to the viewDidLoad method, after instantiating the node for the cube:

The position change moves the camera to the left and up. By adding a constraint, with the cube as its target and gimbalLockEnabled set to true, you ensure that the camera will remain parallel with the horizon and viewport, your device's screen in this case. This is done by disabling rotation along the roll axis, the axis pointing from the camera to the constraint's target.

Build and run your app again, and you will see your cube in all of its 3D glory.

3D cube

4. Materials and Shadows

It's time to add more realism to the scene with materials and shadows. You're first going to need another object to cast a shadow onto. Use the following code snippet to create a plane, a flat rectangle, and position it below the cube. Don't forget to add the new node as a child node to the scene's root node.

By changing the plane node's eulerAngles property, you rotate the plane backwards 90 degrees along the x axis. We need to do this, because planes are created vertically by default. In SceneKit, rotation angles are calculated in radians rather than degrees, but these values can be easily converted using the GLKMathDegreesToRadians(_:) and GLKMathsRadiansToDegrees(_:) functions. GLK stands for GLKit, Apple's OpenGL framework.

Next, add a material to the cube and the plane. For this example, you are going to give the cube and the plane a solid color, red and green respectively. Add the following lines to the viewDidLoad method to create these materials.

For each SCNMaterial object, you assign its diffuse contents a UIColor value. The diffuse property of a material determines how it appears when under direct light. Note that the value assigned does not have to be a UIColor object. There are many other acceptable object types to assign to this property, such as UIImageCALayer, and even a SpriteKit texture (SKTexture).

Build and run your app again to not only see the plane for the first time, but also the materials you created.

Red cube and green plane

Now it's time to add some shadows to your scene. Of the four light types available in SceneKit, only spot lights can create shadows. For this example, you are going to turn your existing omni light into a spot light, targeted towards the cube. Add the following code to the viewDidLoad method:

To create the spot light, you first set the light's type to SCNLightTypeSpot. You then specify the spot light's inner and outer angles in degrees. The default values are 0 and 45 respectively. The inner angle determines how much area the light covers in direct light while the outer angle decides how much area is partially lit. The difference between these angles will become clear once you see the resulting scene. You then explicitly tell the light to cast shadows and also add the same SCNLookAtConstraint that you created for your camera earlier.

Build and run your app to see the resulting scene. The inner angle you specified in your code is shown where the plane is a solid green, directly below the cube. The outer angle is shown by the gradient of light that fades to black as it moves away from the light's target.

Cube and plane with shadow

You'll see that you have now got your cube casting a shadow correctly. The spot light, however, only illuminates part of the plane. This is because there is no ambient light in your scene. 

An ambient light is a light source that illuminates everything with an equal distribution of light. Because an ambient light illuminates the entire scene, its position doesn't matter and you can add it to any node you want, even the same node as your camera. Use the following code snippet to create an ambient light for your scene.

The code snippet creates an SCNLight, just as you did before. The main difference is the light's type property, which is set to SCNLightTypeAmbient. You also set its color to a dark grey so that it doesn't overpower your scene. The default color for a light is pure white (RGB value of 1, 1, 1) and having this color on an ambient light causes the entire scene to be fully illuminated as shown in the screenshot below.

Fully illuminated scene

Build and run your app one last time to see the final result.

Final product

Conclusion

If you've made it to the end of this tutorial, you should now be comfortable with the following topics:

  • the 3D coordinate system and scene graph used by SceneKit
  • setting up an SCNView with an SCNScene
  • adding cameras, lights, and nodes to a scene
  • assigning materials to geometries
  • working with lights to illuminate a scene and cast shadows

In the next tutorial of this series, you will learn about some more advanced concepts of the SceneKit framework, including animation, user interaction, particle systems, and simulating physics.

2015-05-08T16:55:26.000Z2015-05-08T16:55:26.000ZDavis Allie

Google Play Services: Using the Places API

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

In March of 2015, Google released the Places API for Android as a part of Google's Play Services. This API allows developers to access a wealth of information from Google to provide users with an experience tailored to their current location by using the names and information of places, rather than a set of coordinates.

In this tutorial, you will learn how to present your users with the Place Picker component, use the Places API to guess the user's current place, search for a place by its ID, and allow the user to type into a text field to present them with predictive results.

1. Getting Set Up

If you don't already have an Android public API key, you will need to create a public Google API key for Android applications. You can do this by visiting the Google's Developers Console. Instructions for creating a key based on your signing certificate and package name are available in Google's documentation and are beyond the scope of this article.

When you've created a key, search for the Places API and set it to enabled. Some calls to the Places API are limited in how many requests can be sent per 24 hour period. At the time of writing, an account without a billing profile can send up to 1,000 requests while an account with a billing profile can send 150,000 requests. If you require more, you can submit a request to have this limit increased as described in the Usage Limits documentation.

With the API key ready to use, it is time to start working on the demo project. Create a project in Android Studio and set the minimum supported SDK version to at least 9. This is the minimum requirement for using Google's Play Services.

Once Android Studio has created the Hello World template project, open the build.gradle file and, under the dependencies node, add the required dependency of Play Services 7.0. This is the latest at the time of writing, but you can verify the latest version by checking Google's documentation.

Next, open AndroidManifest.xml, add the required permissions for the project, and state that OpenGL version 2 is required by the application.

The last thing you will need to do in the manifest is adding two <meta-data> tags to set the gms version and API key for the app within the <application> tag.

When you're done with the manifest, you are ready to start writing code. As this is a component from Play Services, you will need to initialize your GoogleApiClient and connect/disconnect it during your Activity's life cycle. We do this in the onCreateonStart, and onStop methods of the Activity class.

2. Using the Place Picker Widget

The Place Picker widget is a user interface component provided by Play Services that allows the user to see a map of their surrounding area. The component includes a list of nearby places that can be used by your app. By using this component, you are able to follow a standard design that your users will know how to interact with while being able to save on development time.

Place Picker Widget

To use the Place Picker, you need to create an intent and listen for the Activity result to retrieve the Place selected by the user. The following method shows how you would launch this Activity.

The PlacePicker.IntentBuilder is used to create the Intent that will be used to launch the Place Picker. It also has an method available, setLatLngBounds, that lets you place a geographic boundary from a southwest corner to a northeast corner to control the search area.

The Intent can be built using the build method from PlacePicker.IntentBuilder and launched using the startActivityForResult method from your Activity. It should be noted that using the build method does have the possibility of throwing a GooglePlayServicesRepairableException or a GooglePlayServicesNotAvailableException exception, so those should be checked for using a standard try/catch block and handled gracefully if they occur.

If the user selects a location from the place picker list, that Place object is packaged into an Intent and sent back to the calling Activity. Using the PlacePicker.getPlace method, you can extract the Place data from the returned Intent.

Once the Place object is extracted, it can be treated as a model object to display or use within your app.

The Places API In Action

3. Finding the User's Current Place

Another interesting feature of the Places API is that you can use it to guess if the user is currently at a listed place. The API will also provide a likelihood so that you can make informed decisions about how your app should interact with the user. It should be noted that this is one of the features of the API that requires a request against your allotted usages.

To detect the user's place, you will need to use the Places.PlacesDetectionApi.getCurrentPlace method to create a PendingIntent that returns with a PlaceLikelihoodBuffer object. Using a ResultCallBack, you can take the first, and most likely, place from the buffer and use that in your app.

If your app needs more information, you can extract other PlaceLikelihood items from the buffer by looping through it. The likelihood that this place is where the user is currently located is passed back in each PlaceLikelihood object as a floating point value from 0.0 to 1.0, 1.0 being almost a guaranteed match. Don't forget to call release on the PlaceLikelihoodBuffer to avoid any memory leaks.

Asking the Places API for the Likelihood of the Current Place

4. Predicting Places

The next, and most complex, topic we will go over in this tutorial is predicting and displaying places to the user as they enter a search query. Again, this API call also counts towards the API's usage limits. However, it is invaluable for making your app more useable.

Predicting Places

For this portion of the tutorial, you will use an AutoCompleteTextView and a custom adapter in the app to type the name of a place for predictions. Almost all of the work is done in the adapter. However, we will need to pass a reference to the GoogleApiClient to the adapter for it to access the API.

This can be done in the standard GoogleApiClient callback, onConnected, and we can remove the instance of the client in onStop where mAdapter is an instance of our custom  Adapter class, AutoCompleteAdapter.

To trigger an API call whenever the user types a new letter into the AutoCompleteTextView, you need to override the getFilter method of the ArrayAdapter. This method is triggered whenever the user changes the content of the view associated with the adapter. It allows you to change the content of the adapter of the AutoCompleteTextView. In the following example, constraints is the content of the view.

The displayPredictiveResults method is where the actual interaction with the API occurs. There are a few different objects that can be made to customize your predictions.

The first is a LatLngBounds object that creates a square boundary from a southwest point to a northeast point to localize the query. If null is passed instead of an initialized LatLngBounds object, then no geographic restrictions will be placed on the query.

The second object that you can create to customize the query is a filter for the API request. The filter for the PlacesAutoCompletePredictions call is a list of Integer objects representing different types of filters. At this point, only one filter type can be applied to a query. The acceptable values can be found in the documentation. If the Integer list is empty or null is passed, then all result types are returned.

Once you are ready to make the request, you can use the Places.GeoDataApi.getAutocompletePredictions method to return a PendingIntent, which can be associated with a ResultCallback to display the returned information.

It's important to note that a custom object representing the AutoCompletePrediction objects from the buffer is used to store the data in the ArrayAdapter. Otherwise an IllegalArgumentsException exception would be thrown as soon as the buffer is released, which is crucial to avoid a memory leak.

The content in AutoCompleteAdapter is displayed using a android.R.layout.simple_list_item_1 layout and standard ViewHolder pattern in getView.

When an item is clicked from this list, the ID of the selected Place is passed to the onItemClickedListener and searched for to display.

5. Searching for a Place by ID

The final part of this tutorial covers finding a Place object based on its ID. This works similarly to the other API calls by creating a PendingIntent and interacting with a returned buffer to retrieve the place. Like the other buffer objects you have worked with, the  PlaceBuffer must call release to avoid any memory leaks.

Conclusion

The Places API is a powerful tool for making your apps aware of the user's location to provide them with contextual information. In this tutorial, you have learned how to use the Place Picker component, guess the user's place, present them with predictive results when searching, and find a place based on a given ID. In addition to the topics covered here, it is also possible to submit new places to Google to help expand the information the API has access to.

2015-05-11T15:45:50.000Z2015-05-11T15:45:50.000ZPaul Trebilcox-Ruiz

An Introduction to Volley

$
0
0

Volley is a networking library developed by Google and introduced during Google I/O 2013. It was developed because of the absence, in the Android SDK, of a networking class capable of working without interfering with the user experience.

Until the release of Volley, the canonical Java class java.net.HttpURLConnection and the Apache org.apache.http.client were the only tools available to Android programmers to develop a RESTful system between a client and a remote backend.

Putting aside for a moment the fact that these two classes aren't exempt from bugs, it should be noted how everything that went beyond a simple HTTP transaction had to be written ex novoIf you wanted to cache images or prioritize requests, you had to develop it from scratch.

Fortunately, now there's Volley, created and tailored to fulfill these needs.

1. Why Volley?

Avoid HttpUrlConnection and HttpClient

On lower API levels (mostly on Gingerbread and Froyo), HttpUrlConnection and HttpClient are far from being perfect. There are some knownissues and bugs that were never fixed. Moreover, HttpClient was deprecated in the last API update (API 22), which means that it will no longer be maintained and may be removed in a future release.

These are sufficient reasons for deciding to switch to a more reliable way of handling your network requests.

And Avoid AsyncTask Too

Since the introduction of Honeycomb (API 11), it's been mandatory to perform network operations on a separate thread, different from the main thread. This substantial change led the way to massive use of the AsyncTask<Params, Progress, Result> specification.

With AsyncTask, you first define some preparatory actions, such as the definition of the context, in onPreExecute. You then perform your asynchronous tasks using the doInBackground method. Finally, you handle results in onPostExecute. It's pretty straightforward, way easier than the implementation of a service, and comes with a ton of examples and documentation.

The main problem, however, is the serialization of the calls. Using the AsyncTask class, you can't decide which request goes first and which one has to wait. Everything happens FIFO, first in, first out.

The problems arise, for example, when you have to load a list of items that have attached a thumbnail. When the user scrolls down and expects new results, you can't tell your activity to first load the JSON of the next page and only then the images of the previous one. This can become a serious user experience problem in applications such as Facebook or Twitter, where the list of new items is more important than the thumbnail associated with it.

Volley aims to solve this problem by including a powerful cancellation API. You no longer need to check in onPostExecute whether the activity was destroyed while performing the call. This helps avoiding an unwanted NullPointerException.

It's Much Faster

Some time ago, the Google+ team did a series of performance tests on each of the different methods you can use to make network requests on Android. Volley got a score up to ten times better than the other alternatives when used in RESTful applications.

It Caches Everything

Volley automatically caches requests and this is something truly life-saving. Let’s return for a moment to the example I gave earlier. You have a list of items—a JSON array let’s say—and each item has a description and a thumbnail associated with it. Now think about what happens if the user rotates the screen: the activity is destroyed, the list is downloaded again, and so are the images. Long story short, a significant waste of resources and a poor user experience.

Volley proves to be extremely useful for overcoming this issue. It remembers the previous calls it did and handles the activity destruction and reconstruction. It caches everything without you having to worry about it.

Small Metadata Operations

Volley is perfectfor small calls, such as JSON objects, portions of lists, details of a selected item, and so on. It has been devised for RESTful applications and in this particular case it gives its very best.

It is not so good, however, when employed for streaming operations and large downloads. Contrary to common belief, Volley's name doesn't come from the sport dictionary. It’s rather intended as repeated bursts of calls, grouped together. It's somehow intuitive why this library doesn't come in handy when, instead of a volley of arrows, you want to fire a cannon ball.

2. Under the Hood

Volley works on three different levels with each level operating on its own thread.

Volley under the hood

Main Thread

On the main thread, consistently with what you already do in the AsyncTask specification, you are only allowed to fire the request and handle its response. Nothing more, nothing less.

The main consequence is that you can actually ignore everything that was going on in the doInBackground method. Volley automatically manages the HTTP transactions and the catching network errors that you needed to care about before.

Cache and Network Threads

When you add a request to the queue, several things happens under the hood. First, Volley checks if the request can be serviced from cache. If it can, the cached response is read, parsed, and delivered. Otherwise it is passed to the network thread.

On the network thread, a round-robin with a series of threads is constantly working. The first available network thread dequeues the request, makes the HTTP request, parses the response, and writes it to cache. To finish, it dispatches the parsed response back to the main thread where your listeners are waiting to handle the result.

3. Getting Started

Step 1: Importing Volley

Volley isn't so handy to set up. It looks as if there's no official Maven repository available and this is quite bewildering. You have to rely on the official source code. You can import Volley one of several ways.

First things first, download the Volley source from its repository. If you feel confident doing this, this Git command can do all the work for you:

Until some weeks ago, you could wrap everything up using the ant command line (android update project -p . and then ant jar) and importing your JAR library in your Android Studio project with a simple compile files('libs/volley.jar').

Recently, though, Google updated Volley to the Android Studio build style, making it harder to create a standalone JAR. You can still do it, but only with older versions of the library. I personally discourage you to use this option, even though it may seem the quickest.

You should set up Volley the classic way, that is, by importing the source as a module. In Android Studio, with your project opened, select File > New Module, and choose Import Existing Project. Select the directory where you've just downloaded the source code and confirm. A folder named Volley will show up in your project structure. Android Studio automatically updates your settings.gradle file to include the Volley module so you just need to add to your dependencies compile project(':volley') and you’re done.

There is a third way. You can add to the dependency section of the build.gradle file this line:

It’s a mirror copy of the official Google repository, regularly synced and updated. It's probably the simplest and fastest way to get started. However, be aware, it’s an unofficial Maven repository, no guarantees and not backed by Google.

In my opinion, it's still better to invest a few more minutes importing the official source code. This way, you can easily jump to the original definitions and implementations so that, in case of doubt, you can always rely on the official Volley source—and even change it if you need to.

Step 2: Using Volley

Volley mostly works with just two classes, RequestQueue and Request. You first create a RequestQueue, which manages worker threads and delivers the parsed results back to the main thread. You then pass it one or more Request objects.

The Request constructor always takes as parameters the method type (GET, POST, etc.), the URL of the resource, and event listeners. Then, depending on the type of request, it may ask for some more variables.

In the following example, I create a RequestQueue object by invoking one of Volley's convenience methods, Volley.newRequestQueue. This sets up a RequestQueue object, using default values defined by Volley.

As you can see, it’s incredibly straightforward. You create the request and add it to the request queue. And you’re done.

Note that the listener syntax is similar to AsyncTask.onPostExecute, it simply becomes onResponse. This isn't a coincidence. The developers that worked on Volley purposefully made the library's API so similar to the AsyncTask methods. This makes the transition from using AsyncTask to Volley that much easier.

If you have to fire multiple requests in several activities, you should avoid using the above approach, Volley.newRequestQueue.add. It's much better to instantiate one shared request queue and use it across your project:

We'll see specifically to develop something like this in the next tutorial of this series.

4. Put Your Hands in the Dough

Handling Standard Requests

Volley comes in handy for implementing three very common request types:

  • StringRequest
  • ImageRequest
  • JsonRequest

Each of these classes extend the Result class that we used earlier. We already looked at the StringRequest in the previous example. Let’s see instead how a JsonRequest works.

Beautiful. Isn’t it? As you can see, the type of result is already set to JSONObject. You can ask for a JSONArray too if you want, using a JsonArrayRequest instead of a JsonObjectRequest.

As before, the first parameter of the constructor is the HTTP method to use. You then provide the URL to fetch the JSON from. The third variable in the example above is null. This is fine as it indicates that no parameters will be posted along with the request. Finally, you have the listener to receive the JSON response and an error listener. You can pass in null if you want to ignore errors.

Fetching images require a bit more work. There are three possible methods for requesting an image. ImageRequestis the standard one. It displays the picture you requested in a common ImageView, retrieving it via a provided URL. All the decoding and resizing operations you may want Volley to perform happen on a worker thread. The second option is the ImageLoader class, which you can think of as an orchestrator of a large number of ImageRequests, for example, to populate a ListView with images. The third option is NetworkImageView, which is a sort of XML substitute for the ImageView layout item.

Let’s look at an example.

The first parameter is the URL of the picture and the second one is the listener for the result. The third and fourth parameters are integers, maxWidth and maxHeight. You can set them to 0 to ignore these parameters. After that, ImageRequestasks you for the ScaleType used to calculate the needed image size and for the format to decode the bitmap to. I suggest always using Bitmap.Config.ARGB_8888. Finally, we pass in an error listener.

Note that Volley automatically sets the priority of this request to LOW.

Making a POST Request

Switching from a GET request to a POST request is simple. You need to change the Request.Method in the constructor of the request and override the getParams method, returning a proper Map<String, String> containing the parameters of the request.

Canceling a Request

If you want to cancel all your requests, add the following code snippet to the onStop method:

This way, you don't need to worry about the possibility that the user has already destroyed the activity when onResponse is called. A NullPointerException would be thrown in such a case.

POST and PUT requests, however, should continue, even after the user changes activities. We can accomplish this by using tags. When constructing a GET request, add a tag to it.

To cancel every pending GET request, we simply add the following line of code:

This way, you only cancel the GET requests, leaving other requests untouched. Note that you now have to manually handle the case in which the activity is destroyed prematurely.

Managing Cookies and Request Priority

Volley doesn't provide a method for setting the cookies of a request, nor its priority. It probably will in the future, since it's a serious omission. For the time being, however, you have to extend the Request class.

For managing cookies, you can play with the headers of the request, overriding the getHeaders method:

With this implementation, you can directly provide the list of cookies to the request using setCookies.

For the priority, you also need to extend the Request class, overriding the getPriority method. This is what the implementation could look like:

Then, on the main thread, invoke this line of code to set the priority of the request:

You can choose from one of four possible priority states as shown below:

Conclusion

In this article, we looked at how the Volley networking library works. We first saw why and when it's better to use Volley instead of another solution already included in the Android SDK. We then dove deep into the library's details, looking at its workflow and its supported request types. Finally, we got our hands dirty by creating simple requests and implementing custom ones for handling cookies and prioritization.

In the next part of this series about Volley, we'll create a simple application that leverages Volley. I'll show you how to make a weather application for Mars, using weather data that's collected on Mars by the Curiosity rover.

2015-05-13T17:45:34.000Z2015-05-13T17:45:34.000ZGianluca Segato
Viewing all 1836 articles
Browse latest View live