What’s new in Windows Phone 8.1 Update GDR 1 & specialised code structures of Universal Apps for Windows Store 8.1 & Windows Phone 8.1 app


Recently, there is a new update of Windows Phone 8.1 GDR 1 is available which embeds few new features on existing Windows Phone 8.1 emulator. You can the download it from here. After downloading the pack, let’s check what’s new in this update.

First , you will be prompted with one folder called ‘packages‘ & ‘MobileTools_EmulatorWP81GDR1‘.

MobEmulatorOn clicking, the ‘packages‘ folder, you will be prompted with GDR1 update packages & .cab files.

Update

Now, go ahead with the installation of ‘MobileTools_EmulatorWP81GDR1′ & make sure before proceeding that you should have visual studio 2013 update 2 (at least) to be installed.

Installation

Upon installation, check the available emulators list in visual studio , there are additional emulators are available as ‘Emulator 8.1 U1‘ extension.

Emulators

Let’s checkout a sample Universal app on Windows Store 8.1 & Windows Phone 8.1 app on webview using C#. The project simply consists of Windows Store 8.1, Phone 8.1 & a shared project which consists of app.xaml & shared configuration details.

 

using System.Collections.Generic;
using Windows.UI.Xaml.Controls;

using System;

namespace SDKTemplate
{
public partial class MainPage : Page
{
// Change the string below to reflect the name of your sample.
// This is used on the main page as the title of the sample.
public const string FEATURE_NAME = “XAML WebView control sample”;

// Change the array below to reflect the name of your scenarios.
// This will be used to populate the list of scenarios on the main page with
// which the user will choose the specific scenario that they are interested in.
// These should be in the form: “Navigating to a web page”.
// The code in MainPage will take care of turning this into: “1) Navigating to a web page”
#if WINDOWS_PHONE_APP
List scenarios = new List
{
new Scenario() { Title = “Navigate to a URL”, ClassType = typeof(Controls_WebView.Scenario1) },
new Scenario() { Title = “Navigate to a String”, ClassType = typeof(Controls_WebView.Scenario2) },
new Scenario() { Title = “Navigate to package and local state”, ClassType = typeof(Controls_WebView.Scenario3) },
new Scenario() { Title = “Navigate with custom stream”, ClassType = typeof(Controls_WebView.Scenario4) },
new Scenario() { Title = “Invoke script”, ClassType = typeof(Controls_WebView.Scenario5) },
new Scenario() { Title = “Using ScriptNotify”, ClassType = typeof(Controls_WebView.Scenario6) },
new Scenario() { Title = “Using CaptureBitmap”, ClassType = typeof(Controls_WebView.Scenario8) }
};
#else
List scenarios = new List
{
new Scenario() { Title = “Navigate to a URL”, ClassType = typeof(Controls_WebView.Scenario1) },
new Scenario() { Title = “Navigate to a String”, ClassType = typeof(Controls_WebView.Scenario2) },
new Scenario() { Title = “Navigate to package and local state”, ClassType = typeof(Controls_WebView.Scenario3) },
new Scenario() { Title = “Navigate with custom stream”, ClassType = typeof(Controls_WebView.Scenario4) },
new Scenario() { Title = “Invoke script”, ClassType = typeof(Controls_WebView.Scenario5) },
new Scenario() { Title = “Using ScriptNotify”, ClassType = typeof(Controls_WebView.Scenario6) },
new Scenario() { Title = “Supporting the Share contract”, ClassType = typeof(Controls_WebView.Scenario7) },
new Scenario() { Title = “Using CaptureBitmap”, ClassType = typeof(Controls_WebView.Scenario8) }
};
#endif
}

public class Scenario
{
public string Title { get; set; }

public Type ClassType { get; set; }

public override string ToString()
{
return Title;
}
}
}

SampleConfiguration.cs

  • The ‘Controls_WebView.Shared’ project also consists of a default ‘SuspensionManager.cs’ file contains Session states data in form of Dictionary<string,object> key/value pair.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace SDKTemplate.Common
{
///
/// SuspensionManager captures global session state to simplify process lifetime management
/// for an application. Note that session state will be automatically cleared under a variety
/// of conditions and should only be used to store information that would be convenient to
/// carry across sessions, but that should be discarded when an application crashes or is
/// upgraded.
///

internal sealed class SuspensionManager
{
private static Dictionary<string, object> _sessionState = new Dictionary<string, object>();
private static List _knownTypes = new List();
private const string sessionStateFilename = “_sessionState.xml”;

///
/// Provides access to global session state for the current session. This state is
/// serialized by and restored by
/// , so values must be serializable by
/// and should be as compact as possible. Strings
/// and other self-contained data types are strongly recommended.
///

public static Dictionary<string, object> SessionState
{
get { return _sessionState; }
}

///
/// List of custom types provided to the when
/// reading and writing session state. Initially empty, additional types may be
/// added to customize the serialization process.
///

public static List KnownTypes
{
get { return _knownTypes; }
}

///
/// Save the current . Any instances
/// registered with will also preserve their current
/// navigation stack, which in turn gives their active an opportunity
/// to save its state.
///

/// An asynchronous task that reflects when session state has been saved.
public static async Task SaveAsync()
{
try
{
// Save the navigation state for all registered frames
foreach (var weakFrameReference in _registeredFrames)
{
Frame frame;
if (weakFrameReference.TryGetTarget(out frame))
{
SaveFrameNavigationState(frame);
}
}

// Serialize the session state synchronously to avoid asynchronous access to shared
// state
MemoryStream sessionData = new MemoryStream();
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
serializer.WriteObject(sessionData, _sessionState);

// Get an output stream for the SessionState file and write the state asynchronously
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(sessionStateFilename, CreationCollisionOption.ReplaceExisting);
using (Stream fileStream = await file.OpenStreamForWriteAsync())
{
sessionData.Seek(0, SeekOrigin.Begin);
await sessionData.CopyToAsync(fileStream);
}
}
catch (Exception e)
{
throw new SuspensionManagerException(e);
}
}

///
/// Restores previously saved . Any instances
/// registered with will also restore their prior navigation
/// state, which in turn gives their active an opportunity restore its
/// state.
///

///An optional key that identifies the type of session.
/// This can be used to distinguish between multiple application launch scenarios. /// An asynchronous task that reflects when session state has been read. The
/// content of should not be relied upon until this task
/// completes.
public static async Task RestoreAsync(String sessionBaseKey = null)
{
_sessionState = new Dictionary<String, Object>();

try
{
// Get the input stream for the SessionState file
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(sessionStateFilename);
using (IInputStream inStream = await file.OpenSequentialReadAsync())
{
// Deserialize the Session State
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
_sessionState = (Dictionary<string, object>)serializer.ReadObject(inStream.AsStreamForRead());
}

// Restore any registered frames to their saved state
foreach (var weakFrameReference in _registeredFrames)
{
Frame frame;
if (weakFrameReference.TryGetTarget(out frame) && (string)frame.GetValue(FrameSessionBaseKeyProperty) == sessionBaseKey)
{
frame.ClearValue(FrameSessionStateProperty);
RestoreFrameNavigationState(frame);
}
}
}
catch (Exception e)
{
throw new SuspensionManagerException(e);
}
}

private static DependencyProperty FrameSessionStateKeyProperty =
DependencyProperty.RegisterAttached(“_FrameSessionStateKey”, typeof(String), typeof(SuspensionManager), null);
private static DependencyProperty FrameSessionBaseKeyProperty =
DependencyProperty.RegisterAttached(“_FrameSessionBaseKeyParams”, typeof(String), typeof(SuspensionManager), null);
private static DependencyProperty FrameSessionStateProperty =
DependencyProperty.RegisterAttached(“_FrameSessionState”, typeof(Dictionary<String, Object>), typeof(SuspensionManager), null);
private static List<WeakReference> _registeredFrames = new List<WeakReference>();

///
/// Registers a instance to allow its navigation history to be saved to
/// and restored from . Frames should be registered once
/// immediately after creation if they will participate in session state management. Upon
/// registration if state has already been restored for the specified key
/// the navigation history will immediately be restored. Subsequent invocations of
/// will also restore navigation history.
///

///An instance whose navigation history should be managed by
/// ///A unique key into used to
/// store navigation-related information. ///An optional key that identifies the type of session.
/// This can be used to distinguish between multiple application launch scenarios. public static void RegisterFrame(Frame frame, String sessionStateKey, String sessionBaseKey = null)
{
if (frame.GetValue(FrameSessionStateKeyProperty) != null)
{
throw new InvalidOperationException(“Frames can only be registered to one session state key”);
}

if (frame.GetValue(FrameSessionStateProperty) != null)
{
throw new InvalidOperationException(“Frames must be either be registered before accessing frame session state, or not registered at all”);
}

if (!string.IsNullOrEmpty(sessionBaseKey))
{
frame.SetValue(FrameSessionBaseKeyProperty, sessionBaseKey);
sessionStateKey = sessionBaseKey + “_” + sessionStateKey;
}

// Use a dependency property to associate the session key with a frame, and keep a list of frames whose
// navigation state should be managed
frame.SetValue(FrameSessionStateKeyProperty, sessionStateKey);
_registeredFrames.Add(new WeakReference(frame));

// Check to see if navigation state can be restored
RestoreFrameNavigationState(frame);
}

///
/// Disassociates a previously registered by
/// from . Any navigation state previously captured will be
/// removed.
///

///An instance whose navigation history should no longer be
/// managed. public static void UnregisterFrame(Frame frame)
{
// Remove session state and remove the frame from the list of frames whose navigation
// state will be saved (along with any weak references that are no longer reachable)
SessionState.Remove((String)frame.GetValue(FrameSessionStateKeyProperty));
_registeredFrames.RemoveAll((weakFrameReference) =>
{
Frame testFrame;
return !weakFrameReference.TryGetTarget(out testFrame) || testFrame == frame;
});
}

///
/// Provides storage for session state associated with the specified .
/// Frames that have been previously registered with have
/// their session state saved and restored automatically as a part of the global
/// . Frames that are not registered have transient state
/// that can still be useful when restoring pages that have been discarded from the
/// navigation cache.
///

/// Apps may choose to rely on to manage
/// page-specific state instead of working with frame session state directly.
///The instance for which session state is desired. /// A collection of state subject to the same serialization mechanism as
/// .
public static Dictionary<String, Object> SessionStateForFrame(Frame frame)
{
var frameState = (Dictionary<String, Object>)frame.GetValue(FrameSessionStateProperty);

if (frameState == null)
{
var frameSessionKey = (String)frame.GetValue(FrameSessionStateKeyProperty);
if (frameSessionKey != null)
{
// Registered frames reflect the corresponding session state
if (!_sessionState.ContainsKey(frameSessionKey))
{
_sessionState[frameSessionKey] = new Dictionary<String, Object>();
}
frameState = (Dictionary<String, Object>)_sessionState[frameSessionKey];
}
else
{
// Frames that aren’t registered have transient state
frameState = new Dictionary<String, Object>();
}
frame.SetValue(FrameSessionStateProperty, frameState);
}
return frameState;
}

private static void RestoreFrameNavigationState(Frame frame)
{
var frameState = SessionStateForFrame(frame);
if (frameState.ContainsKey(“Navigation”))
{
frame.SetNavigationState((String)frameState[“Navigation”]);
}
}

private static void SaveFrameNavigationState(Frame frame)
{
var frameState = SessionStateForFrame(frame);
frameState[“Navigation”] = frame.GetNavigationState();
}
}
public class SuspensionManagerException : Exception
{
public SuspensionManagerException()
{
}

public SuspensionManagerException(Exception e)
: base(“SuspensionManager failed”, e)
{

}
}
}

WebControl

Universal App : Windows Phone 8.1 webview app

screenshot_08092014_002735Universal App: Windows Store 8.1 WebView app

Advertisements

About Anindita
Anindita Basak is working as Big Data Cloud Consultant in Microsoft. Worked in multiple MNCs as Developer & Senior Developer on Microsoft Azure, Data Platform, IoT & BI , Data Visualization, Data warehousing & ETL & of course in Hadoop platform.She played both as FTE & v- employee in Azure platform teams of Microsoft.Passionate about .NET , Java, Python & Data Science. She is also an active Big Data & Cloud Trainer & would love share her experience in IT Training Industry. She is an author, forum contributor, blogger & technical reviewer of various books on Big Data Hadoop, HDInsight, IoT & Data Science, SQL Server PDW & PowerBI.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: