Apr 15 2012

Data Serializer updated for Windows Metro

Category: Microsoft | MobileJoel Ivory Johnson @ 12:46

About a year ago I shared a simple utility class for saving serializable data on Windows Phone 7. I just updated the component for Windows 8 Metro. It still retains compatibility with Windows Phone 7 through the use of conditional compiler directives. On Windows Phone 7 I've changed the class so that it is static (so no need to instantiate it). 

For Metro the methos are asynchronous.  For saving an action can be passed that will be called once the save operation is complete. When loading data you'll want to pass an action that will received the loaded data and an exception parameter that will be populated if the data could not be loaded. 

 

As an example of how the code works (and the platform dependent differences in its usage) here is a method from a program I have that is using the code. The program compiles on both Windows Phone 7 and Windows Metro.

        public void LoadAccess()
        {
#if SILVERLIGHT
            AccessInfo = DataSaver<AccessInfo>.LoadMyData("_accessToken.xml");
#endif

#if NETFX_CORE
            DataSaver<AccessInfo>.LoadDataAsync("_accessToken.xml", (info, exc)=>
            {
                if (info != null)
                {
                    this.AccessInfo = info;
                }
            });
#endif
        }

        public void SaveAccessToken()
        {
            if (this.AccessInfo != null)
            {
#if NETFX_CORE
                DataSaver<AccessInfo>.SaveMyDataAsync(this.AccessInfo, "_accessToken.xml");
#endif
#if SILVERLIGHT
               DataSaver<AccessInfo>.SaveMyData(AccessInfo, "_accessToken.xml");
#endif
            }
        }

If you've never seen the #if/#endif directives before it is used to essentially conditionally comment out sections of code based on some condition. In this case the condition is certain compiler constants being defined. Some constants are automatically created for various project types. If you create a windows phone project the WINDOWS_PHONE and SILVERLIGHT constants are defined. For a Windows 8 Metro project the NETFX_CORE constant is defined. When you are viewing the code in the Visual Studio IDE it will gray out any code that is going to be ignored because of the conditional compilation statements. 

Below is the code for the serializer. 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

using System.IO;
#if SILVERLIGHT
using System.IO.IsolatedStorage;
#endif

#if NETFX_CORE
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
#endif

namespace J2i.Net.FacebookAuthenticationTest.Utility
{


    public class DataSaver<MyDataType>
    {

        static List<Type> _knownTypeList = new List<Type>();
        public static List KnownTypeList
        {
            get
            {
                return _knownTypeList;
            }
        }
#if SILVERLIGHT
        private static IsolatedStorageFile _isoFile;
        static IsolatedStorageFile IsoFile
        {
            get
            {
                if (_isoFile == null)
                    _isoFile = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();
                return _isoFile;
            }
        }

         public static void SaveMyData(MyDataType sourceData, String targetFileName)
        {
            try
            {
                using (var targetFile = IsoFile.CreateFile(targetFileName))
                {
                    var d = new DataContractSerializer(typeof(MyDataType), KnownTypeList);
                    d.WriteObject(targetFile, sourceData);
                }
            }
            catch (Exception )
            {
                IsoFile.DeleteFile(targetFileName);
            }
        }


        public static MyDataType LoadMyData(string sourceName)
        {
            MyDataType retVal = default(MyDataType);
            if (IsoFile.FileExists(sourceName))
                using (var sourceStream = IsoFile.OpenFile(sourceName, FileMode.Open))
                {
                    var d = new DataContractSerializer(typeof(MyDataType), KnownTypeList);
                    retVal = (MyDataType)d.ReadObject(sourceStream);
                }
            return retVal;
        }
#endif
        public DataSaver()
        {
        }
#if NETFX_CORE
        public static async void SaveMyDataAsync(
            MyDataType sourceData, 
            String targetFileName, 
            Action<MyDataType,String, Exception> OnSaved = null)
        {
            try
            {
                StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(
                    targetFileName, CreationCollisionOption.ReplaceExisting
                    );
                IRandomAccessStream raStream = await file.OpenAsync(FileAccessMode.ReadWrite);
                IOutputStream outStream = raStream.GetOutputStreamAt(0);

                DataContractSerializer serializer = new DataContractSerializer(typeof(MyDataType), KnownTypeList);
                serializer.WriteObject(outStream.AsStreamForWrite(), sourceData);
                await outStream.FlushAsync();
                if(OnSaved!=null)
                    OnSaved(sourceData, targetFileName, null);
            }
            catch (Exception exc)
            {
                if (OnSaved != null)
                {
                    OnSaved(sourceData, targetFileName, exc);
                }
            }
        }

        public static async void LoadDataAsync(string fileName, Action<MyDataType, Exception> loadAction)
        {
            if (loadAction == null)
                return;
            try
            {
                StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
                if (file == null) return;
                IInputStream inStream = await file.OpenSequentialReadAsync();

                // Deserialize the Session State. 
                DataContractSerializer serializer = new DataContractSerializer(typeof(MyDataType), KnownTypeList);
                MyDataType data = (MyDataType)serializer.ReadObject(inStream.AsStreamForRead());
                loadAction(data, null);
            }
            catch (Exception e)
            {
                loadAction(default(MyDataType), e);
            }
        }
#endif

    }
}

Tags: ,

Mar 27 2012

New Meetup Presentation Series: Getting Started with Windows Phone

Category: Microsoft | MobileJoel Ivory Johnson @ 06:45

Over the next few weeks the Atlanta Windows Phone Developer Meetup group will be having a series of presentations on getting started with Windows Phone development. Many of the presentations will be done by Glen Gordon. I will be doing a few of the presentations too. These presentations are targeting developers that haven't yet gotten started with Windows Phone. So if you've not done any WP development before no worries, these presentations should be fine for you. If you are interested you can find information on the next and future meetings on the Meetup page here: http://www.meetup.com/Win-Phone-7-Developers-Atlanta/

 

Side note: For the presentations I'm doing the functionality works almost exactly the same for Windows Phone and Windows 8. I'm tempted to make an online presentation for both and put it on the web. But the real world presentation will concentrate only on Windows Phone. 

 

Tags: ,

Feb 4 2011

Copy and Paste rolling out for Windows Phone

Category: Microsoft | MobileJoel Ivory Johnson @ 10:38

Microsoft promised Copy and Paste for first quarter 2011, and today they've started to make good on that promise. The update is rolling out to developer's first so that they can test their software and then it will roll out to consumers later. For developers interested in applying the update grab the Windows Phone Developer Tools January 2011 Update.

In the tools you will find updated reference assemblies and a new version of the Emulator that has copy and paste. Your existing applications do not need to be recompiled or changed to take advantage of this update. However, since this update will affect how a tectbox behaves you will want to ensure it doesn't interfere with any textbox interactions that you have designed. For example, if your textbox is inside of another control that accepts text input then the user could encounter difficulty when trying to select text in your application. If this occurs then you'll want to make an update to your application.

The copy and paste update is currently limited to being an update just to the text box. There isn't yet programmatic access to the clip board. But don't worry, that's coming later.

Tags:

Mar 18 2009

MIX09 Announcements

The MIX09 announcements today had me excited.   I didn't make it to Las Vegas but saw the keynoat in the Silverlight streaming interface on http://visitmix.com.

The things that stood out the most to me were the SuperPreview function in Expressions Web 3 (see what your site will look like across several browser versions), lots of improvements in Visual Studio 2010 (Sharepoint debugging, yay!) and lots of other enhanvements for web development.  The most exciting changes of all are occurring within Silverlight 3.0.  It is getting GPU support and full 3D rendering, and support for offline Silverlight applications. The Silverlight betas are available today, but be forewarned that if you install them you will have a Silverlight 3.0 only development environment. 

Rather than repost a summary of the announcements allow me to redirect you to a summary of the announcements here.

Tags: