Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.
Adding support for mobile devices that also interact with SignalR is pretty easy now that we have the basics built. In this section I’ll show a few different approaches for extending the simple survey application to mobile devices. The first uses jQuery Mobile. The second is a native Windows Phone 7 application.
I’ve shown several examples throughout this book that use jQuery Mobile and I mentioned briefly how you can quickly configure ASP.NET MVC 4 to react differently for different devices. However, I haven’t actually shown an example of this in action. Since we already have a web version of the survey application in place, this is a perfect opportunity to quickly walk through what is needed to switch out the views in an ASP.NET MVC 4 web application when a page is accessed by a mobile device.
You first need to add a new _Layout.cshtml file named _Layout.mobile.cshtml. The typical jQuery
Mobile references are then added to this new _Layout file along with the same SignalR, D3,
and mainModule JavaScript references
that were included in the original _Layout file.
All we need to do now is to make a few adjustments to the HTML in the existing Index.cshtml file. With these changes, the one Index.cshtml file can be reused for both views. The markup, with changes emphasized, is as follows:
<divid="survey"class="page"data-role="page" ><divclass="row"data-role="content"><formclass="well"><fieldsetdata-role="controlgroup"><legend>What is your favorite programming language?</legend><divclass="controls"><labelclass="radio"><inputtype="radio"name="langOption"id="fsharp"value="F#"/>F#</label><labelclass="radio"><inputtype="radio"name="langOption"id="csharp"value="C#"/>C#</label><labelclass="radio"><inputtype="radio"name="langOption"id="erlang"value="Erlang"/>Erlang</label><labelclass="radio"><inputtype="radio"name="langOption"id="javascript"value="JavaScript"/>JavaScript</label><labelclass="radio"><inputtype="radio"name="langOption"id="other"value="Other"/>Other</label></div></fieldset><divclass="buttonContainer"><buttonid="vote"class="btn"/>Cast Vote</div></form></div></div><divid="results"class="page"data-role="page" ><divid="barChart"class="barChart"data-role="content" ></div></div>
Instead of using the same Index.cshtml for both views, we could have created a new ASP.NET MVC view named Index.mobile.cshtml to house mobile-specific markup. This is a workable approach if we need to have completely different markup for specific device types; however, I believe it is best to try to keep the markup the same for both views and use media types and other adaptive and/or responsive design techniques to tailor the experience appropriately.
We can verify that things are working by switching out the user agent in a browser such as Chrome. Additionally, we can use emulators and/or simulators such as TestiPhone to see how things will look when displayed on screens of different sizes. The new look with an iPhone 5 user agent on a simulator is shown in Figure 4-3.
While the jQuery Mobile approach will work for all the major mobile players, we may wish to develop specific native apps that also take advantage of SignalR. As an example, perhaps we wish to take our simple survey application and create a native Windows Phone 7 version. The resultant visual aspects of the app are shown in Figure 4-4.
A deep dive into how to create Windows Phone 7 applications in F# could easily fill another book. However, you don’t need to read a whole other book to quickly get a simple Windows Phone 7 app with F# up and running. Simply install the Windows Phone SDK, then install one of the F# and C# Windows Phone project templates from Visual Studio Gallery, such as the one here.
I won’t spend a lot of time going into the details of the non-SignalR aspects of this example. You can find the full source at the GitHub website. One other thing to point out is that this example uses a self-hosted, persistent connection SignalR server. The code for this is available here.
At the time of this writing, the Windows Phone 7 development tools are not yet supported in Visual Studio 2012. Because of this, the example provided in this section uses Visual Studio 2010.
After creating a new F# Windows Phone 7 project, we can add the
desired XAML to
make things appear as shown in Figure 4-4. Next, we need to install the
SignalR.Client NuGet package in both the App and
AppHost projects. We’re now ready to modify the AppLogic.fs file so that it interacts with
the SignalR server.
To get started, we’ll first create a record that will act as a
Model as well as a class to act as a
ViewModel. To keep things simple,
I’ve hardcoded the language choices and associated box color. Each of
these is shown in the following example:
typeLanguageChoice={Language:string;BoxColor:string}typeLanguageChoiceViewModel()=memberx.LanguageChoices=letresult=List<LanguageChoice>()result.Add{Language="F#";BoxColor="#F29925"}result.Add{Language="C#";BoxColor="#5492CD"}result.Add{Language="Erlang";BoxColor="#E41F26"}result.Add{Language="JavaScript";BoxColor="#70BE46"}result.Add{Language="Other";BoxColor="#535353"}result
Model-View-ViewModel (MVVM) is a common design pattern that is often used when building XAML-based solutions. You can find more information about MVVM on John Gossman’s blog. It should be noted that the example provided in this section does not follow MVVM fully. Instead, the example is optimized for simplicity and set up to show different approaches.
Now that the Model and ViewModel are created, we can modify the
MainPage class to include the logic
needed to send the selected vote information to the SignalR server. The
code to accomplish this is shown in the next example and I’ll point out
various interesting aspects in the next several paragraphs:
typeMainPage()asthis=inheritPhoneApplicationPage()dothis.DataContext<-LanguageChoiceViewModel()doApplication.LoadComponent(this,newSystem.Uri("/WindowsPhoneApp;component/MainPage.xaml",System.UriKind.Relative))let confirmationLabel : TextBlock = this?Confirmationmemberthis.AnswerButton_Click(sender:obj,e:RoutedEventArgs)=letanswerButton=sender:?>ButtonSignalR.connection.Send(answerButton.Tag) .Start(TaskScheduler.FromCurrentSynchronizationContext())confirmationLabel.Text<-"Thanks for Voting!"
The first few lines of code in this class are wiring up the class
to the XAML. The class inherits PhoneApplicationPage, sets our ViewModel as the DataContext, and finally associates MainPage.xaml to the class.
The next line locates the TextBlock with a name of Confirmation in the XAML and binds it to a
value named confirmationLabel. This
shows a little bit of the power of the dynamic lookup operator that I
talked about previously in this chapter. In the default output of this
Windows Phone 7 project template, an implementation of the dynamic
lookup operator is provided with the
primary goal of locating resources in a ResourceDictionary or
finding controls in XAML.
The AnswerButton_Click member
shows a traditional code-behind type of click event handler. This is
where we see the first mention of anything related to SignalR. Within
this event handler, we determine which button was pressed and send the
information to the SignalR server by starting the task from the current
synchronization context. Lastly, the text of a label is set to a desired
confirmation message.
The only other thing to discuss is how the SignalR server
connection information is determined. In this example, this is
accomplished by defining a module with a function named startConnection. This function is called
whenever the application launches. Conversely, the connection is stopped
whenever the application is closed. Here is the code for defining the
module with the startConnection
function:
moduleSignalR=letconnection=Connection"http://localhost:8081/chartserver"letstartConnection()=ifconnection.State=ConnectionState.Disconnectedthenconnection.Start().Start(TaskScheduler.FromCurrentSynchronizationContext())