SlideShare a Scribd company logo
1 of 18
Download to read offline
Porting an iPhone Application to Windows Phone 7
Introduction
Developers of iPhone applications possess the fundamentals and key understanding for building
applications for small form factor devices. When creating a mobile application for Windows Phone 7
however, the means for developing the application changes. This platform is a considerable departure
from Microsoft’s previous mobile operating systems so this article will help describe what you’ll
encounter porting an existing iPhone application to Windows Phone 7.
Whether it’s the difference between Objective-C vs .Net, or the iOS SDK vs the Windows Phone 7 SDK, a
number of differences exist which will be explained throughout this article. We’re going to walk through
our own process of porting an internal iPhone application, Slalom Cards, into a comparable version for
Windows Phone 7. The goal of this article is not only provide you with the knowledge necessary to port
an existing application to Windows Phone 7, but to also better understand the platform a whole for new
development.
About the Team
Rob Howard is an experienced software engineer and engineering lead. He has ten
years of industry experience with published mobile applications for several
platforms including iPhone, WebOS, and Blackberry. He has a career in both
Consulting and Startups, building software from the ground up and taking a project
to the latest technologies or methodologies. Rob strives to make solutions simple,
understandable, and easily extendable.
Dan Maycock is a technology solutions consultant, helping advise fortune 500
companies on how to work with new and emerging technologies, primarily focused
around mobile. Prior to working for Slalom Consulting, Dan worked at The Boeing
Company, where he helped shape the direction for enterprise mobility and
successfully pioneered a number of initiatives focused around successfully utilizing
mobile technologies to help solve business challenges.
Greg Martin has been a consultant at Slalom Consulting for over 7 years and is
currently the mobility development lead. Greg is a talented software engineer and
consultant with experience in a wide variety of technologies and industries.
He has spent much of his career delivering solutions in the mobile space. Beyond
his deep technical knowledge, Greg also excels in the entire lifecycle of a project
with an uncanny ability to break a problem down into the most elegant solution.
Slalom Consulting
Slalom Consulting is a business and technology consulting firm that helps clients win by building local
teams with a deep understanding of the art and science of business success. Slalom drives client ROI in
areas such as cloud computing, business intelligence, portals, mobility, project management and process
design. Slalom's consultants are handpicked experts who stay ahead of the curve by always finding the
next innovative advantage. Headquartered in Seattle, Slalom employs more than 800 consultants across
eight cities in the United States.
Slalom Cards
The application listed in this article was built to serve as a dynamic corporate directory, complete with
profile photos, background information and a feature set focused on finding people based on many
characteristics. Originally built for the iPhone, it has since been ported to Android and Windows Phone
7, as well as being extended to a web-based platform.
Getting Ready
Resources
Windows Phone 7 applications are built and tested utilizing Visual Studio. All the tools to get started can
be downloaded at http://developer.windowsphone.com/windows-phone-7/ as well as guides and tips
to get up to speed with the Windows Phone 7 development environment.
As a (fairly obvious) note, the development environment DOES require the Windows Operating System
(Windows Vista or Windows 7), so having either a standalone machine, or a VM with the OS will be
required before you can utilize the Windows Phone 7 development toolset.
You will need to download the developer tools on this website. They are a free download and it
includes the following:
a. Visual Studio 2010 Express for Windows Phone Beta
b. Windows Phone Emulator Beta
c. Silverlight for Windows Phone Beta
d. Microsoft Expression Blend for Windows Phone Beta
e. XNA Game Studio 4.0 Beta
f. The UI Design and Interaction Guide for Windows Phone 7 can be found linked on the
Windows Phone developer site at http://go.microsoft.com/?linkid=9713252
Documentation
Since we are jumping from one platform to another, it’s important to map out the ins and outs of your
existing application. This might include everything from doing a high-level outline, to writing pseudo-
code as a reverse engineering exercise. Regardless, knowing how the application is laid out will help
further down the road once you get deep into the code.
Construction of the Application
The Easy things
Migration of the Data Model
Since the languages support similar features (both object-oriented c-like languages that support things
like properties and methods) porting most of the model items will be pretty straightforward with a one
to one mapping of fields and methods. Note: C# is currently the only supported programming language
for Development for Windows Phone 7.
Networking
Windows Phone 7 allows the developer to use Windows Communication Foundation (WCF),
HttpWebRequest, and WebClient.
WCF works very well with SOAP web services. It is very simple to set up a connection that would
generate all of the networking code and object classes that it uses.
For RESTful services, WCF is also very useful but we will have to do a little bit more work deserializing
the data into objects. There are many ways to do this; .Net provides some simple DataContract
Serializers and Deserializers that work well with XML and JSON.
User Interface Elements
Windows Phone 7 provides a few ways to author and edit the user interface.
One can use the preview pane within the IDE for layout and addition to controls. This is very similar to
the Interface Builder application that is part of the iOS SDK. Users of Interface Builder will become easily
familiar with this method of UI authoring and manipulation.
Also in the IDE is a view of the XAML that can be very useful for a developer to see and modify. This
code behind the presentation is an easy way to see the output of the UI layout engine, and gives a
chance to add function handlers, custom properties on classes, and to fine tune your code.
There is also a version of Expression Studio for the Windows Phone. Like Expression for web based
Silverlight applications or WPF implementations, this provides a more designer focused interface which
allows you to creating templates, behaviors, animations, and many other custom UI.
Page Hierarchy
Like most mobile phone operating systems, Windows Phone 7 provides a stack based navigation system
along with application buttons that can be used, like in the iPhone, as a tabbed based navigation system.
The API provides NavigatedTo and NavigatedFrom methods that are similar to the ViewDidAppear, and
ViewDidDisappear methods that the iPhone supports.
The Difficult and / or Not so clear things
This is a list of things that aren’t as simple as the first list. Differences in hardware, operating systems,
and API are the contributing factor to getting an item in this list.
Data storage
Unlike previous versions of Windows Mobile operating systems, Windows Phone 7 currently does not
have an API for a client-side database which developers can use.
What is provided is access to isolated data storage where your application can save settings or files.
Here you can roll your own data storage mechanism or use a third party database with the caveat that
an application can only access its own data. This is very similar to those familiar with iPhone
development and is another break away from previous versions of Windows Mobile operating systems.
A resource video for developing occasionally connected applications can be found here:
http://www.msteched.com/2010/NorthAmerica/WPH306
Page Transitions
While the navigation between pages in the Windows Phone 7 environment is similar to iPhone, the
familiar animation transitions are not left up to the developer to implement.
Built-in screen transitions and animations are system-reserved and developers cannot access them but
may mimic them. If developers want to implement transitions or animations within their application,
they must use Silverlight or the XNA Framework to create them (see page 64 of the UI Design guide).
Transitions within your application must be implemented on your own.
Contrary to the iPhone, there currently isn’t a defined standard for the types of transitions one should
use.
A Channel9 video of implementation can be seen here:
http://channel9.msdn.com/posts/SlickThought/Simplify-Page-Transitions-in-Windows-Phone-7-
Silverlight-Applications/
Windows Phone 7 Has Themes
There is a large selection of highlight colors including light and dark for background colors.
One must be aware that the user could have any one of those themes set for their phone. The
application should be aware of the settings and use them throughout the user experience.
Background images and UI elements presented above them should take in to account the possibility of
the different themes. For example, if you use a particularly dark image for a background, the light
theme with black button borders may not show up very well against the image. Setting the opacity of
the image to show some of the white background is one solution to this problem.
Digging Deeper
The following are some examples that we used in Slalom Cards. We chose these examples because we
felt that they are things that aren’t obvious to most developers and take some research to find a
solution. We also feel that they are things that pretty much any application for the phone would need.
Some are simplified versions of examples that others have created or ones that we fixed due to the SDK
changes in the Windows Phone 7 in its push to production. In our samples, we try to find a simple
solution to the problems while providing the best user experience.
Porting the Data Model – The following is simple port of a small class from Objective-C to C#. This
would be part of a class that would represent the data behind user interface elements. It could be
created in several different ways, like being fetched from storage, from an external API, or being
generated by the application at runtime. In the example, the extra methods for those means of creation
or fetching have been omitted to keep the code short:
Person.h
@interface Person : NSObject
{
}
@property (nonatomic, retain) NSString * firstName;
@property (nonatomic, retain) NSString * lastName;
@property (nonatomic, retain) NSString * office;
Person.m
#import "Person.h"
@implementation Person
@synthesize firstName;
@synthesize lastName;
@synthesize office;
-(void)dealloc
{
[firstName release];
[lastName release];
[office release];
[super dealloc];
}
@end
Person.cs
public class Person
{
public String FirstName { get; set; }
public String LastName { get; set; }
public String Office { get; set; }
}
C# also provides an easy way to port Observable objects. The following code is an
update of the Person class to notify observers of updates to the data.
public class Person : INotifyPropertyChanged
{
private String firstName;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyChanged(String changeProperty)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(changeProperty));
}
}
public String FirstName
{
get
{
return firstName;
}
set
{
if (value != firstName)
{
firstName = value;
NotifyChanged("FirstName");
}
}
}
…
Navigation – Moving from page to page in your application is different than iPhone, but fairly simple.
Instead of pushing and popping view controllers to your scene, the navigation system behaves more like
a browser where you navigate forward and back through the pages of the application. Also, data is
passed to the pages through the querystring where the navigating page can read and perform
operations based on the input. This is shown in the following examples:
A typical navigation operation in iPhone
PersonListViewController * personList = [[PersonListViewController alloc]
initWithNibName:@"PersonList" bundle:nil];
[[self navigationController] pushViewController: personList animated:YES];
[personList release];
Doing the same in code on Windows Phone 7
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/PersonListPage.xaml?office=Seattle",
UriKind.Relative));
}
A different way, with XAML
<HyperlinkButton Content="Seattle" NavigateUri="/PersonListPage.xaml?office=Seattle" />
<HyperlinkButton Content="Los Angeles" NavigateUri="/PersonListPage.xaml?office=Los Angeles" />
Reading passed in values on the new page
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
PersonList people = CardsDatabase.Instance.PersonListTable;
string office;
if (NavigationContext.QueryString.TryGetValue("office", out office) == false)
{
office = "National"; // default value
}
PersonList.ItemsSource =
from p in people
where p.Office == office // filter to the selected office
orderby p.FirstName, p.LastName
select p;
}
Navigating back to the previous page is either done with the user clicking on the
back hardware button or you can programmatically perform this with the following
code:
NavigationService.GoBack();
Page Transitions – As stated earlier, the Windows Phone 7 SDK leaves it up to the developer to create
animations and transitions while navigating between pages. A simple way to add these transitions to
your application is to use the TransitioningContentControl in the Microsoft Silverlight Toolkit found at
http://silverlight.codeplex.com/. The steps to add these transitions are as follows:
1. Download and install the toolkit.
2. Add a reference in your project to
System.Windows.Controls.Layout.Toolkit.dll (for example after installation,
it was found in: Program Files (x86)Microsoft
SDKsSilverlightv4.0ToolkitApr10BinSystem.Windows.Controls.Layout.Toolk
it.dll)
3. In your App.xaml file, create a Style for the application frame that
includes a TransitioningContentControl
<Application
x:Class="Cards.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:tcc ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Layout.Toolkit"
>
<Application.Resources>
<Style x:Key="mainFrameStyle"
TargetType="phone:PhoneApplicationFrame">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border x:Name="ClientArea"
BorderBrush="{TemplateBinding
BorderBrush}"
BorderThickness="{TemplateBinding
BorderThickness}"
Background="{TemplateBinding
Background}"
HorizontalAlignment="{TemplateBinding
HorizontalAlignment}"
VerticalAlignment="{TemplateBinding
VerticalAlignment}">
<tcc:TransitioningContentControl
x:Name="TransitioningControl" Content="{TemplateBinding Content}" Style="{StaticResource
TransitioningStyle}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Also in this file, create the transition templates for the page transitions. For
the example, a SwingOpen transition for navigating forward and a SwingClosed
transition for backward navigation.
<Style x:Key="TransitioningStyle" TargetType="tcc:TransitioningContentControl">
<Setter Property="Transition" Value="SwingOpen" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="layout:TransitioningContentControl">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2">
<VisualStateManager.VisualStateGroups>
<VisualState x:Name="SwingOpen">
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)"
Storyboard.TargetName="PreviousContentPresentationSite">
<EasingDoubleKeyFrame
KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame
KeyTime="0:0:0.4" Value="90"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="PreviousContentPresentationSite">
<EasingDoubleKeyFrame
KeyTime="0:0:0.3" Value="1"/>
<EasingDoubleKeyFrame
KeyTime="0:0:0.4" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimation Duration="0"
To="0"
Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)"
Storyboard.TargetName="PreviousContentPresentationSite" />
<DoubleAnimation Duration="0"
To="0"
Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)"
Storyboard.TargetName="CurrentContentPresentationSite" />
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="CurrentContentPresentationSite">
<EasingDoubleKeyFrame
KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame
KeyTime="0:0:0.4" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="SwingClosed">
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="PreviousContentPresentationSite">
<EasingDoubleKeyFrame
KeyTime="0:0:0.3" Value="1"/>
<EasingDoubleKeyFrame
KeyTime="0:0:0.4" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimation Duration="0"
To="0"
Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)"
Storyboard.TargetName="PreviousContentPresentationSite" />
<DoubleAnimation Duration="0"
To="0"
Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)"
Storyboard.TargetName="CurrentContentPresentationSite" />
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)"
Storyboard.TargetName="CurrentContentPresentationSite">
<EasingDoubleKeyFrame
KeyTime="0" Value="90"/>
<EasingDoubleKeyFrame
KeyTime="0:0:0.4" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="CurrentContentPresentationSite">
<EasingDoubleKeyFrame
KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame
KeyTime="0:0:0.4" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<ContentPresenter
x:Name="PreviousContentPresentationSite"
Content="{x:Null}"
ContentTemplate="{TemplateBinding
ContentTemplate}">
<ContentPresenter.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</ContentPresenter.RenderTransform>
<ContentPresenter.Projection>
<PlaneProjection />
</ContentPresenter.Projection>
</ContentPresenter>
<ContentPresenter
x:Name="CurrentContentPresentationSite"
Content="{x:Null}"
ContentTemplate="{TemplateBinding
ContentTemplate}" >
<ContentPresenter.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</ContentPresenter.RenderTransform>
<ContentPresenter.Projection>
<PlaneProjection />
</ContentPresenter.Projection>
</ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In the app.xaml.cs, set the style of the root frame to the new style created in
the previous step.
RootFrame = new PhoneApplicationFrame()
{
// Use a style to use the Template with the TransitioningContentControl
Style = (Style)Resources["mainFrameStyle"]
};
Right now, this is all that one would need to do to implement a transition between pages. However, it
will show the same “SwingOpen” transition navigating forward and back. But, like the transitions in
iPhone, it is a clearer user experience to show a different transition for backward navigation than
forward. This can be accomplished with the following steps:
Extend the TransitioningContentControl class, set up a Setter for the transition
that would be used:
public class CardsTransitioningContentControl : TransitioningContentControl
{
private static String _currentTransition = "SwingOpen";
public static void SetBackTransition()
{
_currentTransition = "SwingClosed";
}
public static void SetForwardTransition()
{
_currentTransition = "SwingOpen";
}
protected override void OnContentChanged(object oldContent, object newContent)
{
Transition = _currentTransition;
base.OnContentChanged(oldContent, newContent);
SetForwardTransition(); // reset to the default
}
}
In the PhoneApplicationPage class, capture the back button press and update the
transition
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
CardsTransitioningContentControl.SetBack();
base.OnBackKeyPress(e);
}
Orientation Transitions – Like page transitions, it is up to the developer to implement a transition for
orientation changes. This can be done by overriding the application frame class and registering an event
listener for the OrientationChanged event. The Cards implementation is a simplified version of the
sample from: http://blogs.msdn.com/b/delay/archive/2010/07/13/spin-spin-sugar-updated-code-to-
easily-animate-orientation-changes-for-any-windows-phone-application.aspx. This example is nice
because it will size the content as it rotates providing a fluid transition between states.
First, create a new subclass of PhoneApplicationFrame and have the App.xaml.cs instantiate it when it
creates the frame.
In the InitializePhoneApplication method of App.xaml.cs
RootFrame = new CardsApplicationFrame()
Then fill in the details of the PhoneApplicationFrame subclass
public class CardsApplicationFrame : PhoneApplicationFrame
{
private readonly RotateTransform _rotateTransform = new RotateTransform();
private readonly Storyboard _orientationStoryboard = new Storyboard();
private readonly DoubleAnimation _orientationAnimation = new DoubleAnimation();
private readonly OrientationState _fromOrientationState = new OrientationState();
private readonly OrientationState _toOrientationState = new OrientationState();
private UIElement _clientArea;
private Size _lastSize;
public CardsApplicationFrame()
{
RenderTransform = _rotateTransform;
RenderTransformOrigin = new Point(0.5, 0.5);
_orientationAnimation.From = 0;
_orientationAnimation.To = 1;
_orientationAnimation.Duration = new Duration(TimeSpan.FromSeconds(.4));
_orientationAnimation.EasingFunction = new QuarticEase();
Storyboard.SetTarget(_orientationAnimation, this);
Storyboard.SetTargetProperty(_orientationAnimation, new
PropertyPath("OrientationProgress"));
_orientationStoryboard.Children.Add(_orientationAnimation);
SizeChanged += new SizeChangedEventHandler(HandleSizeChanged);
OrientationChanged += new
EventHandler<OrientationChangedEventArgs>(HandleOrientationChanged);
}
private static readonly DependencyProperty ProgressProperty =
DependencyProperty.Register(
"OrientationProgress",
typeof(double),
typeof(CardsApplicationFrame),
new PropertyMetadata(0.0, OnProgressChanged));
private static void OnProgressChanged(DependencyObject o,
DependencyPropertyChangedEventArgs e)
{
((CardsApplicationFrame)o).OnProgressChanged((double)e.NewValue);
}
private void OnProgressChanged(double newValue)
{
_rotateTransform.Angle = _fromOrientationState.Angle +
(newValue * (_toOrientationState.Angle - _fromOrientationState.Angle));
var width = _fromOrientationState.Width +
(newValue * (_toOrientationState.Width - _fromOrientationState.Width));
var height = _fromOrientationState.Height +
(newValue * (_toOrientationState.Height - _fromOrientationState.Height));
var size = new Size(Math.Round(width), Math.Round(height));
if (size != _lastSize)
{
_lastSize = size;
InvalidateMeasure();
}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_clientArea = base.GetTemplateChild("ClientArea") as UIElement;
}
private void HandleSizeChanged(object sender, SizeChangedEventArgs e)
{
_fromOrientationState.Width = e.NewSize.Width;
_fromOrientationState.Height = e.NewSize.Height;
_lastSize = e.NewSize;
InvalidateMeasure();
}
private void HandleOrientationChanged(object sender, OrientationChangedEventArgs e)
{
_fromOrientationState.Angle = _rotateTransform.Angle;
_fromOrientationState.Width = _lastSize.Width;
_fromOrientationState.Height = _lastSize.Height;
_orientationStoryboard.Stop();
// Determine new angle
switch (e.Orientation)
{
case PageOrientation.PortraitUp:
_toOrientationState.Angle = 0;
break;
case PageOrientation.LandscapeLeft:
_toOrientationState.Angle = 90;
break;
case PageOrientation.LandscapeRight:
_toOrientationState.Angle = -90;
break;
case PageOrientation.PortraitDown:
_toOrientationState.Angle = 180;
break;
default:
throw new NotSupportedException("Unknown PageOrientation
value.");
}
// Determine new size
var actualWidth = ActualWidth;
var actualHeight = ActualHeight;
var toPortrait = (0 == (_toOrientationState.Angle % 180));
_toOrientationState.Width = toPortrait ? actualWidth : actualHeight;
_toOrientationState.Height = toPortrait ? actualHeight : actualWidth;
_orientationStoryboard.Begin();
}
protected override Size MeasureOverride(Size availableSize)
{
if (null != _clientArea)
{
// Adjust measure size to transition size
var newValue = (double)GetValue(ProgressProperty);
var width = _fromOrientationState.Width +
(newValue * (_toOrientationState.Width -
_fromOrientationState.Width));
var height = _fromOrientationState.Height +
(newValue * (_toOrientationState.Height -
_fromOrientationState.Height));
_clientArea.Measure(new Size(width, height));
}
// Return default size
return availableSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
if (null != _clientArea)
{
var newValue = (double)GetValue(ProgressProperty);
var width = _fromOrientationState.Width +
(newValue * (_toOrientationState.Width -
_fromOrientationState.Width));
var height = _fromOrientationState.Height +
(newValue * (_toOrientationState.Height -
_fromOrientationState.Height));
_clientArea.Arrange(new Rect((finalSize.Width - width) / 2,
(finalSize.Height - height) / 2, width, height));
}
return finalSize;
}
private class OrientationState
{
public double Width { get; set; }
public double Height { get; set; }
public double Angle { get; set; }
}
}
Networking – The following is an example of a base request class that is used to send an asynchronous
request to a server. It allows for different request methods, and will call handler methods upon
completion of the request.
public abstract class CardsRequestBase
{
…
public void SendRequestToService()
{
String url = GetURL();
_request = (HttpWebRequest)WebRequest.Create(url);
// set any headers like authentication, cache options, etc
SetRequestHeaders(_request);
_request.Method = GetMethod();
// Is it a request that requires data to be added?
if (_request.Method.Equals("POST") || _request.Method.Equals("PUT"))
{
_request.BeginGetRequestStream(new AsyncCallback(SendDataToStream),
_request);
}
else
{
SendRequest();
}
}
private void SendDataToStream(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
String postData = GetContentData();
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
postStream.Write(byteArray, 0, postData.Length);
postStream.Close();
SendRequest();
}
private void SendRequest()
{
IAsyncResult result = _request.BeginGetResponse(new
AsyncCallback(HandleResponse), this);
ThreadPool.RegisterWaitForSingleObject(
result.AsyncWaitHandle,
new WaitOrTimerCallback(RequestTimeoutCallback), this,
(GetTimeoutSeconds() * 1000), true);
}
protected virtual String GetContentData()
{
return "";
}
protected virtual void SetRequestHeaders(HttpWebRequest request)
{
}
private void RequestTimeoutCallback(Object state, bool timedOut)
{
if (timedOut)
{
CancelRequest();
}
}
protected virtual void HandleResponse(IAsyncResult result)
{
try
{
HttpWebResponse response =
(HttpWebResponse)_request.EndGetResponse(result);
using (Stream responseStream = response.GetResponseStream())
{
HandleResponseStream(responseStream);
// extra processing option for subclasses
// this is here to take advantage of performing
// needed operations (like parsing) on the background thread
PostResponseProcessing();
}
}
catch (Exception e)
{
_error = e;
}
if (_requestHandler != null)
{
if (_error == null)
{
_requestHandler.RequestCompletedWithResults(_results, this);
}
else
{
_requestHandler.RequestCompletedWithError(_error, this);
}
}
}
// Broke this out to its own method so that classes can override as needed
protected virtual void HandleResponseStream(Stream responseStream)
{
using (StreamReader reader = new StreamReader(responseStream))
{
_results = reader.ReadToEnd();
reader.Close();
responseStream.Close();
}
}
Data Serialization – The server for Slalom Cards provides a RESTful service for the data that the client
consumes. We took advantage of the XMLSerializer to parse the responses from the server, and to store
data in the Isolated Storage on the device. The service’s responses were in XML, but a JSON response
would be just as easy to handle with the DataContractJsonSerializer class. The following snippets of
code are examples of the use of the XMLSerializer in SlalomCards:
The Collection Class
// Parse a collection of People objects, the root of the collection will be the element "People"
// like <People>... people list .. </People>
[XmlRoot(ElementName = "People")]
public class PersonList : ObservableCollection<Person>
{
}
The Person Class: Note the INotifyPropertyChanged interface. This is used to
notify clients, like binding clients of updates. (Like KVO in iPhone).
// Will Parse into a Person Object where the Element name is "P"
[XmlRootAttribute("P",Namespace="", IsNullable = false)]
public class Person : INotifyPropertyChanged
{
private Guid _ID;
private String _action;
public Person()
{
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyChanged(String changeProperty)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(changeProperty));
}
}
[XmlAttribute(AttributeName="id")]
public Guid ID
{
get
{
return _ID;
}
set
{
if (value != _ID)
{
_ID = value;
NotifyChanged("ID");
}
}
}
[XmlAttribute(DataType = "string", AttributeName = "ac")]
public String Action
{
get
{
return _action;
}
set
{
if (value != _action)
{
_action = value;
NotifyChanged("Action");
}
}
}
…
Reading the PersonList object data from a stream. This could be a HTTP Response
Stream, a File Stream, Memory Stream, etc.
using (stream)
{
// Read the personList object from the stream
XmlSerializer ser = new XmlSerializer(typeof(PersonList));
_personListTable = (PersonList)ser.Deserialize(stream);
}
Data Storage – The Slalom Cards application persists data by taking advantage of data serialization,
isolated storage, and LINQ to fetch, sort, and filter the data. A resource video for developing
occasionally connected applications that was the inspiration for the example can be found at:
http://www.msteched.com/2010/NorthAmerica/WPH306
First create a Singleton for Database Management
sealed class CardsDatabase
{
private PersonList _personListTable = null;
private CardsDatabase()
{ }
private static CardsDatabase _staticDB = new CardsDatabase();
public static CardsDatabase Instance
{
get
{
return _staticDB;
}
}
Then Create the Table members of the Database Class that will fetch the data, (in
the same CardsDatabase class)
private PersonList _personListTable = null;
public PersonList PersonListTable
{
get
{
if (_personListTable == null)
{
using (IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForApplication())
{
Stream stream = null;
if (store.FileExists(_personListFile))
{
stream = store.OpenFile(_personListFile, FileMode.Open);
using (stream)
{
// Read the personList object from the stream
XmlSerializer ser = new
XmlSerializer(typeof(PersonList));
_personListTable = (PersonList)ser.ReadObject(stream);
}
}
}
}
return _personListTable;
}
}
Finally, create a LINQ query to fetch the data as your application needs it:
PersonList people = CardsDatabase.Instance.PersonListTable;
ListBox.ItemsSource =
from p in people
where p.Office == "Seattle"
orderby p.FirstName, p.LastName
select p;
…
Concluding Thoughts
There are many things with Windows Phone 7 that an iPhone developer will find familiar and be
comfortable with, but a few things that have a bit of a learning curve. Since the capabilities of the
devices are so similar, functionality can be mirrored from iPhone to WP7. However, they are two
different worlds and so there is still work associated with your first ported application. We hope this
article will help clarify some of these differences, and will help you to develop Windows Phone 7
applications in a more efficient, streamlined, manner.

More Related Content

What's hot

Cross platform app a comparative study
Cross platform app  a comparative studyCross platform app  a comparative study
Cross platform app a comparative studyijcsit
 
Introducing Windows Phone 8 Development
Introducing Windows Phone 8 DevelopmentIntroducing Windows Phone 8 Development
Introducing Windows Phone 8 DevelopmentDave Bost
 
Pradeep_iOS_Developer
Pradeep_iOS_DeveloperPradeep_iOS_Developer
Pradeep_iOS_DeveloperPradeep kn
 
Introduction To Mobile Application Development
Introduction To Mobile Application DevelopmentIntroduction To Mobile Application Development
Introduction To Mobile Application DevelopmentSyed Absar
 
Unit 1 vb study_materials
Unit 1 vb study_materialsUnit 1 vb study_materials
Unit 1 vb study_materialsgayaramesh
 
B feigin mobileapplicationdevelopment
B feigin mobileapplicationdevelopmentB feigin mobileapplicationdevelopment
B feigin mobileapplicationdevelopmentsathesh leo
 
Apps vs. Sites vs. Content - a vendor-agnostic view on building stuff for the...
Apps vs. Sites vs. Content - a vendor-agnostic view on building stuff for the...Apps vs. Sites vs. Content - a vendor-agnostic view on building stuff for the...
Apps vs. Sites vs. Content - a vendor-agnostic view on building stuff for the...Kai Koenig
 
A Glimpse On MeeGo
A Glimpse On MeeGoA Glimpse On MeeGo
A Glimpse On MeeGoAmanda Lam
 
Android overview
Android overviewAndroid overview
Android overviewbhavani p
 

What's hot (18)

Cross platform app a comparative study
Cross platform app  a comparative studyCross platform app  a comparative study
Cross platform app a comparative study
 
Stc ftn-wp7-intro
Stc ftn-wp7-introStc ftn-wp7-intro
Stc ftn-wp7-intro
 
Introducing Windows Phone 8 Development
Introducing Windows Phone 8 DevelopmentIntroducing Windows Phone 8 Development
Introducing Windows Phone 8 Development
 
App development
App developmentApp development
App development
 
Mobile Programming
Mobile Programming Mobile Programming
Mobile Programming
 
Pradeep_iOS_Developer
Pradeep_iOS_DeveloperPradeep_iOS_Developer
Pradeep_iOS_Developer
 
Introduction To Mobile Application Development
Introduction To Mobile Application DevelopmentIntroduction To Mobile Application Development
Introduction To Mobile Application Development
 
Unit 1 vb study_materials
Unit 1 vb study_materialsUnit 1 vb study_materials
Unit 1 vb study_materials
 
B feigin mobileapplicationdevelopment
B feigin mobileapplicationdevelopmentB feigin mobileapplicationdevelopment
B feigin mobileapplicationdevelopment
 
Windows 7 mobile
Windows 7 mobileWindows 7 mobile
Windows 7 mobile
 
ImranBaigCV
ImranBaigCVImranBaigCV
ImranBaigCV
 
Apps vs. Sites vs. Content - a vendor-agnostic view on building stuff for the...
Apps vs. Sites vs. Content - a vendor-agnostic view on building stuff for the...Apps vs. Sites vs. Content - a vendor-agnostic view on building stuff for the...
Apps vs. Sites vs. Content - a vendor-agnostic view on building stuff for the...
 
Company2
Company2Company2
Company2
 
A Glimpse On MeeGo
A Glimpse On MeeGoA Glimpse On MeeGo
A Glimpse On MeeGo
 
Windows phone7 subodh
Windows phone7 subodhWindows phone7 subodh
Windows phone7 subodh
 
Jellybean
JellybeanJellybean
Jellybean
 
Android overview
Android overviewAndroid overview
Android overview
 
Android overview
Android overviewAndroid overview
Android overview
 

Viewers also liked

Windows Phone 7 Unleashed Session 1
Windows Phone 7 Unleashed Session 1Windows Phone 7 Unleashed Session 1
Windows Phone 7 Unleashed Session 1Wes Yanaga
 
Windows Phone 7 Unleashed Session 2
Windows Phone 7 Unleashed Session 2Windows Phone 7 Unleashed Session 2
Windows Phone 7 Unleashed Session 2Wes Yanaga
 
Pinned Sites IE 9 Lightup
Pinned Sites IE 9 LightupPinned Sites IE 9 Lightup
Pinned Sites IE 9 LightupWes Yanaga
 
Microsoft Partner Benefits for Software Companies
Microsoft Partner Benefits for Software CompaniesMicrosoft Partner Benefits for Software Companies
Microsoft Partner Benefits for Software CompaniesWes Yanaga
 
Windows Phone 7 Now
Windows Phone 7 NowWindows Phone 7 Now
Windows Phone 7 NowWes Yanaga
 
Office 365 for Developers
Office 365 for DevelopersOffice 365 for Developers
Office 365 for DevelopersWes Yanaga
 

Viewers also liked (7)

Private cloud
Private cloudPrivate cloud
Private cloud
 
Windows Phone 7 Unleashed Session 1
Windows Phone 7 Unleashed Session 1Windows Phone 7 Unleashed Session 1
Windows Phone 7 Unleashed Session 1
 
Windows Phone 7 Unleashed Session 2
Windows Phone 7 Unleashed Session 2Windows Phone 7 Unleashed Session 2
Windows Phone 7 Unleashed Session 2
 
Pinned Sites IE 9 Lightup
Pinned Sites IE 9 LightupPinned Sites IE 9 Lightup
Pinned Sites IE 9 Lightup
 
Microsoft Partner Benefits for Software Companies
Microsoft Partner Benefits for Software CompaniesMicrosoft Partner Benefits for Software Companies
Microsoft Partner Benefits for Software Companies
 
Windows Phone 7 Now
Windows Phone 7 NowWindows Phone 7 Now
Windows Phone 7 Now
 
Office 365 for Developers
Office 365 for DevelopersOffice 365 for Developers
Office 365 for Developers
 

Similar to Porting iPhone Apps to Windows Phone 7

Benefits of PhoneGap for Mobile App Development - Appzure
Benefits of PhoneGap for Mobile App Development - AppzureBenefits of PhoneGap for Mobile App Development - Appzure
Benefits of PhoneGap for Mobile App Development - AppzureAppzure -Mobile App Development
 
Mobile Developer's Guide To The Galaxy 12th Edition
Mobile Developer's Guide To The Galaxy 12th EditionMobile Developer's Guide To The Galaxy 12th Edition
Mobile Developer's Guide To The Galaxy 12th EditionMarco Tabor
 
Mobile Developer's Guide To The Galaxy, 14th Edition
Mobile Developer's Guide To The Galaxy, 14th EditionMobile Developer's Guide To The Galaxy, 14th Edition
Mobile Developer's Guide To The Galaxy, 14th EditionMarco Tabor
 
UNIT_1_1626771386169.ppt
UNIT_1_1626771386169.pptUNIT_1_1626771386169.ppt
UNIT_1_1626771386169.pptHannaAnvar1
 
Mobile App Development Tools For Building Apps
Mobile App Development Tools For Building AppsMobile App Development Tools For Building Apps
Mobile App Development Tools For Building AppsXongoLab Technologies LLP
 
Windowsphone7
Windowsphone7Windowsphone7
Windowsphone7yuvaraj72
 
Native v s hybrid
Native v s hybridNative v s hybrid
Native v s hybridKelly Ston
 
Enough_Software_Guide_16thEdition_Web
Enough_Software_Guide_16thEdition_WebEnough_Software_Guide_16thEdition_Web
Enough_Software_Guide_16thEdition_WebMarco Tabor
 
Mobile app developers guide
Mobile app developers guideMobile app developers guide
Mobile app developers guidePrayukth K V
 
Hybrid Mobile App Development Frameworks 2016
Hybrid Mobile App Development Frameworks 2016Hybrid Mobile App Development Frameworks 2016
Hybrid Mobile App Development Frameworks 2016PixelCrayons
 
MOBILE APPLICATIONS DEVELOPMENT AND SERVICES.pptx
MOBILE APPLICATIONS DEVELOPMENT AND SERVICES.pptxMOBILE APPLICATIONS DEVELOPMENT AND SERVICES.pptx
MOBILE APPLICATIONS DEVELOPMENT AND SERVICES.pptxmuthulakshmi cse
 
Step-by-Step Guide to Developing a Successful iOS App.docx
Step-by-Step Guide to Developing a Successful iOS App.docxStep-by-Step Guide to Developing a Successful iOS App.docx
Step-by-Step Guide to Developing a Successful iOS App.docxBytes Technolab Inc.
 
The ultimate guide and facts on cross platform app development in 2021.
The ultimate guide and facts on cross platform app development in 2021.The ultimate guide and facts on cross platform app development in 2021.
The ultimate guide and facts on cross platform app development in 2021.Concetto Labs
 
Step-by-Step Guide to Developing a Successful iOS App.pdf
Step-by-Step Guide to Developing a Successful iOS App.pdfStep-by-Step Guide to Developing a Successful iOS App.pdf
Step-by-Step Guide to Developing a Successful iOS App.pdfBytes Technolab Inc.
 
Here are the Most Useful Tools for Mobile App Development
Here are the Most Useful Tools for Mobile App DevelopmentHere are the Most Useful Tools for Mobile App Development
Here are the Most Useful Tools for Mobile App DevelopmentIndianAppDevelopers
 
Mobile Devolpment Slides
Mobile Devolpment SlidesMobile Devolpment Slides
Mobile Devolpment SlidesLuke Angel
 
How to build PhoneGap App for Windows Phone?
How to build PhoneGap App for Windows Phone?How to build PhoneGap App for Windows Phone?
How to build PhoneGap App for Windows Phone?MobilePundits
 
iOS7-User-Experience-Shootout
iOS7-User-Experience-ShootoutiOS7-User-Experience-Shootout
iOS7-User-Experience-ShootoutGeoffrey Dorne
 
Mobile Developers Guide To The Galaxy Vol.6
Mobile Developers Guide To The Galaxy Vol.6Mobile Developers Guide To The Galaxy Vol.6
Mobile Developers Guide To The Galaxy Vol.6Marco Tabor
 
Why windows phone
Why windows phoneWhy windows phone
Why windows phonePawan Kurmi
 

Similar to Porting iPhone Apps to Windows Phone 7 (20)

Benefits of PhoneGap for Mobile App Development - Appzure
Benefits of PhoneGap for Mobile App Development - AppzureBenefits of PhoneGap for Mobile App Development - Appzure
Benefits of PhoneGap for Mobile App Development - Appzure
 
Mobile Developer's Guide To The Galaxy 12th Edition
Mobile Developer's Guide To The Galaxy 12th EditionMobile Developer's Guide To The Galaxy 12th Edition
Mobile Developer's Guide To The Galaxy 12th Edition
 
Mobile Developer's Guide To The Galaxy, 14th Edition
Mobile Developer's Guide To The Galaxy, 14th EditionMobile Developer's Guide To The Galaxy, 14th Edition
Mobile Developer's Guide To The Galaxy, 14th Edition
 
UNIT_1_1626771386169.ppt
UNIT_1_1626771386169.pptUNIT_1_1626771386169.ppt
UNIT_1_1626771386169.ppt
 
Mobile App Development Tools For Building Apps
Mobile App Development Tools For Building AppsMobile App Development Tools For Building Apps
Mobile App Development Tools For Building Apps
 
Windowsphone7
Windowsphone7Windowsphone7
Windowsphone7
 
Native v s hybrid
Native v s hybridNative v s hybrid
Native v s hybrid
 
Enough_Software_Guide_16thEdition_Web
Enough_Software_Guide_16thEdition_WebEnough_Software_Guide_16thEdition_Web
Enough_Software_Guide_16thEdition_Web
 
Mobile app developers guide
Mobile app developers guideMobile app developers guide
Mobile app developers guide
 
Hybrid Mobile App Development Frameworks 2016
Hybrid Mobile App Development Frameworks 2016Hybrid Mobile App Development Frameworks 2016
Hybrid Mobile App Development Frameworks 2016
 
MOBILE APPLICATIONS DEVELOPMENT AND SERVICES.pptx
MOBILE APPLICATIONS DEVELOPMENT AND SERVICES.pptxMOBILE APPLICATIONS DEVELOPMENT AND SERVICES.pptx
MOBILE APPLICATIONS DEVELOPMENT AND SERVICES.pptx
 
Step-by-Step Guide to Developing a Successful iOS App.docx
Step-by-Step Guide to Developing a Successful iOS App.docxStep-by-Step Guide to Developing a Successful iOS App.docx
Step-by-Step Guide to Developing a Successful iOS App.docx
 
The ultimate guide and facts on cross platform app development in 2021.
The ultimate guide and facts on cross platform app development in 2021.The ultimate guide and facts on cross platform app development in 2021.
The ultimate guide and facts on cross platform app development in 2021.
 
Step-by-Step Guide to Developing a Successful iOS App.pdf
Step-by-Step Guide to Developing a Successful iOS App.pdfStep-by-Step Guide to Developing a Successful iOS App.pdf
Step-by-Step Guide to Developing a Successful iOS App.pdf
 
Here are the Most Useful Tools for Mobile App Development
Here are the Most Useful Tools for Mobile App DevelopmentHere are the Most Useful Tools for Mobile App Development
Here are the Most Useful Tools for Mobile App Development
 
Mobile Devolpment Slides
Mobile Devolpment SlidesMobile Devolpment Slides
Mobile Devolpment Slides
 
How to build PhoneGap App for Windows Phone?
How to build PhoneGap App for Windows Phone?How to build PhoneGap App for Windows Phone?
How to build PhoneGap App for Windows Phone?
 
iOS7-User-Experience-Shootout
iOS7-User-Experience-ShootoutiOS7-User-Experience-Shootout
iOS7-User-Experience-Shootout
 
Mobile Developers Guide To The Galaxy Vol.6
Mobile Developers Guide To The Galaxy Vol.6Mobile Developers Guide To The Galaxy Vol.6
Mobile Developers Guide To The Galaxy Vol.6
 
Why windows phone
Why windows phoneWhy windows phone
Why windows phone
 

More from Wes Yanaga

Hyper-v Cloud
Hyper-v Cloud Hyper-v Cloud
Hyper-v Cloud Wes Yanaga
 
windows phone-developer-guidance-map- 2-d00_-v2
windows phone-developer-guidance-map- 2-d00_-v2windows phone-developer-guidance-map- 2-d00_-v2
windows phone-developer-guidance-map- 2-d00_-v2Wes Yanaga
 
Azure Discover Event Silicon Valley
Azure Discover Event Silicon ValleyAzure Discover Event Silicon Valley
Azure Discover Event Silicon ValleyWes Yanaga
 
Business Opportunity for Windows Phone 7
Business Opportunity for Windows Phone 7Business Opportunity for Windows Phone 7
Business Opportunity for Windows Phone 7Wes Yanaga
 
Mpr walkthrough
Mpr walkthroughMpr walkthrough
Mpr walkthroughWes Yanaga
 
Intro to c# (vs. objective c and java)
Intro to c# (vs. objective c and java)Intro to c# (vs. objective c and java)
Intro to c# (vs. objective c and java)Wes Yanaga
 

More from Wes Yanaga (6)

Hyper-v Cloud
Hyper-v Cloud Hyper-v Cloud
Hyper-v Cloud
 
windows phone-developer-guidance-map- 2-d00_-v2
windows phone-developer-guidance-map- 2-d00_-v2windows phone-developer-guidance-map- 2-d00_-v2
windows phone-developer-guidance-map- 2-d00_-v2
 
Azure Discover Event Silicon Valley
Azure Discover Event Silicon ValleyAzure Discover Event Silicon Valley
Azure Discover Event Silicon Valley
 
Business Opportunity for Windows Phone 7
Business Opportunity for Windows Phone 7Business Opportunity for Windows Phone 7
Business Opportunity for Windows Phone 7
 
Mpr walkthrough
Mpr walkthroughMpr walkthrough
Mpr walkthrough
 
Intro to c# (vs. objective c and java)
Intro to c# (vs. objective c and java)Intro to c# (vs. objective c and java)
Intro to c# (vs. objective c and java)
 

Recently uploaded

unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 

Recently uploaded (20)

unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 

Porting iPhone Apps to Windows Phone 7

  • 1. Porting an iPhone Application to Windows Phone 7 Introduction Developers of iPhone applications possess the fundamentals and key understanding for building applications for small form factor devices. When creating a mobile application for Windows Phone 7 however, the means for developing the application changes. This platform is a considerable departure from Microsoft’s previous mobile operating systems so this article will help describe what you’ll encounter porting an existing iPhone application to Windows Phone 7. Whether it’s the difference between Objective-C vs .Net, or the iOS SDK vs the Windows Phone 7 SDK, a number of differences exist which will be explained throughout this article. We’re going to walk through our own process of porting an internal iPhone application, Slalom Cards, into a comparable version for Windows Phone 7. The goal of this article is not only provide you with the knowledge necessary to port an existing application to Windows Phone 7, but to also better understand the platform a whole for new development. About the Team Rob Howard is an experienced software engineer and engineering lead. He has ten years of industry experience with published mobile applications for several platforms including iPhone, WebOS, and Blackberry. He has a career in both Consulting and Startups, building software from the ground up and taking a project to the latest technologies or methodologies. Rob strives to make solutions simple, understandable, and easily extendable. Dan Maycock is a technology solutions consultant, helping advise fortune 500 companies on how to work with new and emerging technologies, primarily focused around mobile. Prior to working for Slalom Consulting, Dan worked at The Boeing Company, where he helped shape the direction for enterprise mobility and successfully pioneered a number of initiatives focused around successfully utilizing mobile technologies to help solve business challenges. Greg Martin has been a consultant at Slalom Consulting for over 7 years and is currently the mobility development lead. Greg is a talented software engineer and consultant with experience in a wide variety of technologies and industries. He has spent much of his career delivering solutions in the mobile space. Beyond his deep technical knowledge, Greg also excels in the entire lifecycle of a project with an uncanny ability to break a problem down into the most elegant solution. Slalom Consulting Slalom Consulting is a business and technology consulting firm that helps clients win by building local teams with a deep understanding of the art and science of business success. Slalom drives client ROI in
  • 2. areas such as cloud computing, business intelligence, portals, mobility, project management and process design. Slalom's consultants are handpicked experts who stay ahead of the curve by always finding the next innovative advantage. Headquartered in Seattle, Slalom employs more than 800 consultants across eight cities in the United States. Slalom Cards The application listed in this article was built to serve as a dynamic corporate directory, complete with profile photos, background information and a feature set focused on finding people based on many characteristics. Originally built for the iPhone, it has since been ported to Android and Windows Phone 7, as well as being extended to a web-based platform. Getting Ready Resources Windows Phone 7 applications are built and tested utilizing Visual Studio. All the tools to get started can be downloaded at http://developer.windowsphone.com/windows-phone-7/ as well as guides and tips to get up to speed with the Windows Phone 7 development environment. As a (fairly obvious) note, the development environment DOES require the Windows Operating System (Windows Vista or Windows 7), so having either a standalone machine, or a VM with the OS will be required before you can utilize the Windows Phone 7 development toolset. You will need to download the developer tools on this website. They are a free download and it includes the following: a. Visual Studio 2010 Express for Windows Phone Beta b. Windows Phone Emulator Beta c. Silverlight for Windows Phone Beta d. Microsoft Expression Blend for Windows Phone Beta e. XNA Game Studio 4.0 Beta f. The UI Design and Interaction Guide for Windows Phone 7 can be found linked on the Windows Phone developer site at http://go.microsoft.com/?linkid=9713252 Documentation Since we are jumping from one platform to another, it’s important to map out the ins and outs of your existing application. This might include everything from doing a high-level outline, to writing pseudo- code as a reverse engineering exercise. Regardless, knowing how the application is laid out will help further down the road once you get deep into the code. Construction of the Application The Easy things
  • 3. Migration of the Data Model Since the languages support similar features (both object-oriented c-like languages that support things like properties and methods) porting most of the model items will be pretty straightforward with a one to one mapping of fields and methods. Note: C# is currently the only supported programming language for Development for Windows Phone 7. Networking Windows Phone 7 allows the developer to use Windows Communication Foundation (WCF), HttpWebRequest, and WebClient. WCF works very well with SOAP web services. It is very simple to set up a connection that would generate all of the networking code and object classes that it uses. For RESTful services, WCF is also very useful but we will have to do a little bit more work deserializing the data into objects. There are many ways to do this; .Net provides some simple DataContract Serializers and Deserializers that work well with XML and JSON. User Interface Elements Windows Phone 7 provides a few ways to author and edit the user interface. One can use the preview pane within the IDE for layout and addition to controls. This is very similar to the Interface Builder application that is part of the iOS SDK. Users of Interface Builder will become easily familiar with this method of UI authoring and manipulation. Also in the IDE is a view of the XAML that can be very useful for a developer to see and modify. This code behind the presentation is an easy way to see the output of the UI layout engine, and gives a chance to add function handlers, custom properties on classes, and to fine tune your code. There is also a version of Expression Studio for the Windows Phone. Like Expression for web based Silverlight applications or WPF implementations, this provides a more designer focused interface which allows you to creating templates, behaviors, animations, and many other custom UI. Page Hierarchy Like most mobile phone operating systems, Windows Phone 7 provides a stack based navigation system along with application buttons that can be used, like in the iPhone, as a tabbed based navigation system. The API provides NavigatedTo and NavigatedFrom methods that are similar to the ViewDidAppear, and ViewDidDisappear methods that the iPhone supports. The Difficult and / or Not so clear things
  • 4. This is a list of things that aren’t as simple as the first list. Differences in hardware, operating systems, and API are the contributing factor to getting an item in this list. Data storage Unlike previous versions of Windows Mobile operating systems, Windows Phone 7 currently does not have an API for a client-side database which developers can use. What is provided is access to isolated data storage where your application can save settings or files. Here you can roll your own data storage mechanism or use a third party database with the caveat that an application can only access its own data. This is very similar to those familiar with iPhone development and is another break away from previous versions of Windows Mobile operating systems. A resource video for developing occasionally connected applications can be found here: http://www.msteched.com/2010/NorthAmerica/WPH306 Page Transitions While the navigation between pages in the Windows Phone 7 environment is similar to iPhone, the familiar animation transitions are not left up to the developer to implement. Built-in screen transitions and animations are system-reserved and developers cannot access them but may mimic them. If developers want to implement transitions or animations within their application, they must use Silverlight or the XNA Framework to create them (see page 64 of the UI Design guide). Transitions within your application must be implemented on your own. Contrary to the iPhone, there currently isn’t a defined standard for the types of transitions one should use. A Channel9 video of implementation can be seen here: http://channel9.msdn.com/posts/SlickThought/Simplify-Page-Transitions-in-Windows-Phone-7- Silverlight-Applications/ Windows Phone 7 Has Themes There is a large selection of highlight colors including light and dark for background colors. One must be aware that the user could have any one of those themes set for their phone. The application should be aware of the settings and use them throughout the user experience. Background images and UI elements presented above them should take in to account the possibility of the different themes. For example, if you use a particularly dark image for a background, the light theme with black button borders may not show up very well against the image. Setting the opacity of
  • 5. the image to show some of the white background is one solution to this problem. Digging Deeper The following are some examples that we used in Slalom Cards. We chose these examples because we felt that they are things that aren’t obvious to most developers and take some research to find a solution. We also feel that they are things that pretty much any application for the phone would need. Some are simplified versions of examples that others have created or ones that we fixed due to the SDK changes in the Windows Phone 7 in its push to production. In our samples, we try to find a simple solution to the problems while providing the best user experience. Porting the Data Model – The following is simple port of a small class from Objective-C to C#. This would be part of a class that would represent the data behind user interface elements. It could be created in several different ways, like being fetched from storage, from an external API, or being generated by the application at runtime. In the example, the extra methods for those means of creation or fetching have been omitted to keep the code short: Person.h @interface Person : NSObject { } @property (nonatomic, retain) NSString * firstName; @property (nonatomic, retain) NSString * lastName; @property (nonatomic, retain) NSString * office; Person.m #import "Person.h" @implementation Person @synthesize firstName; @synthesize lastName; @synthesize office; -(void)dealloc { [firstName release]; [lastName release]; [office release]; [super dealloc]; } @end Person.cs public class Person { public String FirstName { get; set; } public String LastName { get; set; } public String Office { get; set; } }
  • 6. C# also provides an easy way to port Observable objects. The following code is an update of the Person class to notify observers of updates to the data. public class Person : INotifyPropertyChanged { private String firstName; public event PropertyChangedEventHandler PropertyChanged; private void NotifyChanged(String changeProperty) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(changeProperty)); } } public String FirstName { get { return firstName; } set { if (value != firstName) { firstName = value; NotifyChanged("FirstName"); } } } … Navigation – Moving from page to page in your application is different than iPhone, but fairly simple. Instead of pushing and popping view controllers to your scene, the navigation system behaves more like a browser where you navigate forward and back through the pages of the application. Also, data is passed to the pages through the querystring where the navigating page can read and perform operations based on the input. This is shown in the following examples: A typical navigation operation in iPhone PersonListViewController * personList = [[PersonListViewController alloc] initWithNibName:@"PersonList" bundle:nil]; [[self navigationController] pushViewController: personList animated:YES]; [personList release]; Doing the same in code on Windows Phone 7 private void HyperlinkButton_Click(object sender, RoutedEventArgs e) { NavigationService.Navigate(new Uri("/PersonListPage.xaml?office=Seattle", UriKind.Relative)); } A different way, with XAML <HyperlinkButton Content="Seattle" NavigateUri="/PersonListPage.xaml?office=Seattle" /> <HyperlinkButton Content="Los Angeles" NavigateUri="/PersonListPage.xaml?office=Los Angeles" /> Reading passed in values on the new page
  • 7. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { base.OnNavigatedTo(e); PersonList people = CardsDatabase.Instance.PersonListTable; string office; if (NavigationContext.QueryString.TryGetValue("office", out office) == false) { office = "National"; // default value } PersonList.ItemsSource = from p in people where p.Office == office // filter to the selected office orderby p.FirstName, p.LastName select p; } Navigating back to the previous page is either done with the user clicking on the back hardware button or you can programmatically perform this with the following code: NavigationService.GoBack(); Page Transitions – As stated earlier, the Windows Phone 7 SDK leaves it up to the developer to create animations and transitions while navigating between pages. A simple way to add these transitions to your application is to use the TransitioningContentControl in the Microsoft Silverlight Toolkit found at http://silverlight.codeplex.com/. The steps to add these transitions are as follows: 1. Download and install the toolkit. 2. Add a reference in your project to System.Windows.Controls.Layout.Toolkit.dll (for example after installation, it was found in: Program Files (x86)Microsoft SDKsSilverlightv4.0ToolkitApr10BinSystem.Windows.Controls.Layout.Toolk it.dll) 3. In your App.xaml file, create a Style for the application frame that includes a TransitioningContentControl <Application x:Class="Cards.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:tcc ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Layout.Toolkit" > <Application.Resources> <Style x:Key="mainFrameStyle" TargetType="phone:PhoneApplicationFrame"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Border x:Name="ClientArea" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
  • 8. Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"> <tcc:TransitioningContentControl x:Name="TransitioningControl" Content="{TemplateBinding Content}" Style="{StaticResource TransitioningStyle}"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> Also in this file, create the transition templates for the page transitions. For the example, a SwingOpen transition for navigating forward and a SwingClosed transition for backward navigation. <Style x:Key="TransitioningStyle" TargetType="tcc:TransitioningContentControl"> <Setter Property="Transition" Value="SwingOpen" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="layout:TransitioningContentControl"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"> <VisualStateManager.VisualStateGroups> <VisualState x:Name="SwingOpen"> <Storyboard> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="PreviousContentPresentationSite"> <EasingDoubleKeyFrame KeyTime="0" Value="0"/> <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="90"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PreviousContentPresentationSite"> <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/> <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)" Storyboard.TargetName="PreviousContentPresentationSite" /> <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)" Storyboard.TargetName="CurrentContentPresentationSite" />
  • 9. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="CurrentContentPresentationSite"> <EasingDoubleKeyFrame KeyTime="0" Value="0"/> <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="1"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="SwingClosed"> <Storyboard> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PreviousContentPresentationSite"> <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/> <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)" Storyboard.TargetName="PreviousContentPresentationSite" /> <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.CenterOfRotationX)" Storyboard.TargetName="CurrentContentPresentationSite" /> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="CurrentContentPresentationSite"> <EasingDoubleKeyFrame KeyTime="0" Value="90"/> <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="CurrentContentPresentationSite"> <EasingDoubleKeyFrame KeyTime="0" Value="0"/> <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="1"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups>
  • 10. <Grid> <ContentPresenter x:Name="PreviousContentPresentationSite" Content="{x:Null}" ContentTemplate="{TemplateBinding ContentTemplate}"> <ContentPresenter.RenderTransform> <TransformGroup> <ScaleTransform /> <SkewTransform /> <RotateTransform /> <TranslateTransform /> </TransformGroup> </ContentPresenter.RenderTransform> <ContentPresenter.Projection> <PlaneProjection /> </ContentPresenter.Projection> </ContentPresenter> <ContentPresenter x:Name="CurrentContentPresentationSite" Content="{x:Null}" ContentTemplate="{TemplateBinding ContentTemplate}" > <ContentPresenter.RenderTransform> <TransformGroup> <ScaleTransform /> <SkewTransform /> <RotateTransform /> <TranslateTransform /> </TransformGroup> </ContentPresenter.RenderTransform> <ContentPresenter.Projection> <PlaneProjection /> </ContentPresenter.Projection> </ContentPresenter> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> In the app.xaml.cs, set the style of the root frame to the new style created in the previous step. RootFrame = new PhoneApplicationFrame() { // Use a style to use the Template with the TransitioningContentControl Style = (Style)Resources["mainFrameStyle"] }; Right now, this is all that one would need to do to implement a transition between pages. However, it will show the same “SwingOpen” transition navigating forward and back. But, like the transitions in iPhone, it is a clearer user experience to show a different transition for backward navigation than forward. This can be accomplished with the following steps: Extend the TransitioningContentControl class, set up a Setter for the transition that would be used: public class CardsTransitioningContentControl : TransitioningContentControl
  • 11. { private static String _currentTransition = "SwingOpen"; public static void SetBackTransition() { _currentTransition = "SwingClosed"; } public static void SetForwardTransition() { _currentTransition = "SwingOpen"; } protected override void OnContentChanged(object oldContent, object newContent) { Transition = _currentTransition; base.OnContentChanged(oldContent, newContent); SetForwardTransition(); // reset to the default } } In the PhoneApplicationPage class, capture the back button press and update the transition protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e) { CardsTransitioningContentControl.SetBack(); base.OnBackKeyPress(e); } Orientation Transitions – Like page transitions, it is up to the developer to implement a transition for orientation changes. This can be done by overriding the application frame class and registering an event listener for the OrientationChanged event. The Cards implementation is a simplified version of the sample from: http://blogs.msdn.com/b/delay/archive/2010/07/13/spin-spin-sugar-updated-code-to- easily-animate-orientation-changes-for-any-windows-phone-application.aspx. This example is nice because it will size the content as it rotates providing a fluid transition between states. First, create a new subclass of PhoneApplicationFrame and have the App.xaml.cs instantiate it when it creates the frame. In the InitializePhoneApplication method of App.xaml.cs RootFrame = new CardsApplicationFrame() Then fill in the details of the PhoneApplicationFrame subclass public class CardsApplicationFrame : PhoneApplicationFrame { private readonly RotateTransform _rotateTransform = new RotateTransform(); private readonly Storyboard _orientationStoryboard = new Storyboard(); private readonly DoubleAnimation _orientationAnimation = new DoubleAnimation(); private readonly OrientationState _fromOrientationState = new OrientationState(); private readonly OrientationState _toOrientationState = new OrientationState(); private UIElement _clientArea; private Size _lastSize; public CardsApplicationFrame() { RenderTransform = _rotateTransform; RenderTransformOrigin = new Point(0.5, 0.5);
  • 12. _orientationAnimation.From = 0; _orientationAnimation.To = 1; _orientationAnimation.Duration = new Duration(TimeSpan.FromSeconds(.4)); _orientationAnimation.EasingFunction = new QuarticEase(); Storyboard.SetTarget(_orientationAnimation, this); Storyboard.SetTargetProperty(_orientationAnimation, new PropertyPath("OrientationProgress")); _orientationStoryboard.Children.Add(_orientationAnimation); SizeChanged += new SizeChangedEventHandler(HandleSizeChanged); OrientationChanged += new EventHandler<OrientationChangedEventArgs>(HandleOrientationChanged); } private static readonly DependencyProperty ProgressProperty = DependencyProperty.Register( "OrientationProgress", typeof(double), typeof(CardsApplicationFrame), new PropertyMetadata(0.0, OnProgressChanged)); private static void OnProgressChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { ((CardsApplicationFrame)o).OnProgressChanged((double)e.NewValue); } private void OnProgressChanged(double newValue) { _rotateTransform.Angle = _fromOrientationState.Angle + (newValue * (_toOrientationState.Angle - _fromOrientationState.Angle)); var width = _fromOrientationState.Width + (newValue * (_toOrientationState.Width - _fromOrientationState.Width)); var height = _fromOrientationState.Height + (newValue * (_toOrientationState.Height - _fromOrientationState.Height)); var size = new Size(Math.Round(width), Math.Round(height)); if (size != _lastSize) { _lastSize = size; InvalidateMeasure(); } } public override void OnApplyTemplate() { base.OnApplyTemplate(); _clientArea = base.GetTemplateChild("ClientArea") as UIElement; } private void HandleSizeChanged(object sender, SizeChangedEventArgs e) { _fromOrientationState.Width = e.NewSize.Width; _fromOrientationState.Height = e.NewSize.Height; _lastSize = e.NewSize; InvalidateMeasure(); } private void HandleOrientationChanged(object sender, OrientationChangedEventArgs e) { _fromOrientationState.Angle = _rotateTransform.Angle; _fromOrientationState.Width = _lastSize.Width; _fromOrientationState.Height = _lastSize.Height; _orientationStoryboard.Stop(); // Determine new angle
  • 13. switch (e.Orientation) { case PageOrientation.PortraitUp: _toOrientationState.Angle = 0; break; case PageOrientation.LandscapeLeft: _toOrientationState.Angle = 90; break; case PageOrientation.LandscapeRight: _toOrientationState.Angle = -90; break; case PageOrientation.PortraitDown: _toOrientationState.Angle = 180; break; default: throw new NotSupportedException("Unknown PageOrientation value."); } // Determine new size var actualWidth = ActualWidth; var actualHeight = ActualHeight; var toPortrait = (0 == (_toOrientationState.Angle % 180)); _toOrientationState.Width = toPortrait ? actualWidth : actualHeight; _toOrientationState.Height = toPortrait ? actualHeight : actualWidth; _orientationStoryboard.Begin(); } protected override Size MeasureOverride(Size availableSize) { if (null != _clientArea) { // Adjust measure size to transition size var newValue = (double)GetValue(ProgressProperty); var width = _fromOrientationState.Width + (newValue * (_toOrientationState.Width - _fromOrientationState.Width)); var height = _fromOrientationState.Height + (newValue * (_toOrientationState.Height - _fromOrientationState.Height)); _clientArea.Measure(new Size(width, height)); } // Return default size return availableSize; } protected override Size ArrangeOverride(Size finalSize) { if (null != _clientArea) { var newValue = (double)GetValue(ProgressProperty); var width = _fromOrientationState.Width + (newValue * (_toOrientationState.Width - _fromOrientationState.Width)); var height = _fromOrientationState.Height + (newValue * (_toOrientationState.Height - _fromOrientationState.Height)); _clientArea.Arrange(new Rect((finalSize.Width - width) / 2, (finalSize.Height - height) / 2, width, height)); } return finalSize; } private class OrientationState {
  • 14. public double Width { get; set; } public double Height { get; set; } public double Angle { get; set; } } } Networking – The following is an example of a base request class that is used to send an asynchronous request to a server. It allows for different request methods, and will call handler methods upon completion of the request. public abstract class CardsRequestBase { … public void SendRequestToService() { String url = GetURL(); _request = (HttpWebRequest)WebRequest.Create(url); // set any headers like authentication, cache options, etc SetRequestHeaders(_request); _request.Method = GetMethod(); // Is it a request that requires data to be added? if (_request.Method.Equals("POST") || _request.Method.Equals("PUT")) { _request.BeginGetRequestStream(new AsyncCallback(SendDataToStream), _request); } else { SendRequest(); } } private void SendDataToStream(IAsyncResult asynchronousResult) { HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; Stream postStream = request.EndGetRequestStream(asynchronousResult); String postData = GetContentData(); byte[] byteArray = Encoding.UTF8.GetBytes(postData); postStream.Write(byteArray, 0, postData.Length); postStream.Close(); SendRequest(); } private void SendRequest() { IAsyncResult result = _request.BeginGetResponse(new AsyncCallback(HandleResponse), this); ThreadPool.RegisterWaitForSingleObject( result.AsyncWaitHandle, new WaitOrTimerCallback(RequestTimeoutCallback), this, (GetTimeoutSeconds() * 1000), true); } protected virtual String GetContentData() { return ""; } protected virtual void SetRequestHeaders(HttpWebRequest request) { }
  • 15. private void RequestTimeoutCallback(Object state, bool timedOut) { if (timedOut) { CancelRequest(); } } protected virtual void HandleResponse(IAsyncResult result) { try { HttpWebResponse response = (HttpWebResponse)_request.EndGetResponse(result); using (Stream responseStream = response.GetResponseStream()) { HandleResponseStream(responseStream); // extra processing option for subclasses // this is here to take advantage of performing // needed operations (like parsing) on the background thread PostResponseProcessing(); } } catch (Exception e) { _error = e; } if (_requestHandler != null) { if (_error == null) { _requestHandler.RequestCompletedWithResults(_results, this); } else { _requestHandler.RequestCompletedWithError(_error, this); } } } // Broke this out to its own method so that classes can override as needed protected virtual void HandleResponseStream(Stream responseStream) { using (StreamReader reader = new StreamReader(responseStream)) { _results = reader.ReadToEnd(); reader.Close(); responseStream.Close(); } } Data Serialization – The server for Slalom Cards provides a RESTful service for the data that the client consumes. We took advantage of the XMLSerializer to parse the responses from the server, and to store data in the Isolated Storage on the device. The service’s responses were in XML, but a JSON response would be just as easy to handle with the DataContractJsonSerializer class. The following snippets of code are examples of the use of the XMLSerializer in SlalomCards: The Collection Class // Parse a collection of People objects, the root of the collection will be the element "People"
  • 16. // like <People>... people list .. </People> [XmlRoot(ElementName = "People")] public class PersonList : ObservableCollection<Person> { } The Person Class: Note the INotifyPropertyChanged interface. This is used to notify clients, like binding clients of updates. (Like KVO in iPhone). // Will Parse into a Person Object where the Element name is "P" [XmlRootAttribute("P",Namespace="", IsNullable = false)] public class Person : INotifyPropertyChanged { private Guid _ID; private String _action; public Person() { } public event PropertyChangedEventHandler PropertyChanged; private void NotifyChanged(String changeProperty) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(changeProperty)); } } [XmlAttribute(AttributeName="id")] public Guid ID { get { return _ID; } set { if (value != _ID) { _ID = value; NotifyChanged("ID"); } } } [XmlAttribute(DataType = "string", AttributeName = "ac")] public String Action { get { return _action; } set { if (value != _action) { _action = value; NotifyChanged("Action"); } } } …
  • 17. Reading the PersonList object data from a stream. This could be a HTTP Response Stream, a File Stream, Memory Stream, etc. using (stream) { // Read the personList object from the stream XmlSerializer ser = new XmlSerializer(typeof(PersonList)); _personListTable = (PersonList)ser.Deserialize(stream); } Data Storage – The Slalom Cards application persists data by taking advantage of data serialization, isolated storage, and LINQ to fetch, sort, and filter the data. A resource video for developing occasionally connected applications that was the inspiration for the example can be found at: http://www.msteched.com/2010/NorthAmerica/WPH306 First create a Singleton for Database Management sealed class CardsDatabase { private PersonList _personListTable = null; private CardsDatabase() { } private static CardsDatabase _staticDB = new CardsDatabase(); public static CardsDatabase Instance { get { return _staticDB; } } Then Create the Table members of the Database Class that will fetch the data, (in the same CardsDatabase class) private PersonList _personListTable = null; public PersonList PersonListTable { get { if (_personListTable == null) { using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) { Stream stream = null; if (store.FileExists(_personListFile)) { stream = store.OpenFile(_personListFile, FileMode.Open); using (stream) { // Read the personList object from the stream XmlSerializer ser = new XmlSerializer(typeof(PersonList)); _personListTable = (PersonList)ser.ReadObject(stream); } } } } return _personListTable;
  • 18. } } Finally, create a LINQ query to fetch the data as your application needs it: PersonList people = CardsDatabase.Instance.PersonListTable; ListBox.ItemsSource = from p in people where p.Office == "Seattle" orderby p.FirstName, p.LastName select p; … Concluding Thoughts There are many things with Windows Phone 7 that an iPhone developer will find familiar and be comfortable with, but a few things that have a bit of a learning curve. Since the capabilities of the devices are so similar, functionality can be mirrored from iPhone to WP7. However, they are two different worlds and so there is still work associated with your first ported application. We hope this article will help clarify some of these differences, and will help you to develop Windows Phone 7 applications in a more efficient, streamlined, manner.