Difference between LocalSettings and IsolatedStorageSettings - windows-phone-8.1

I am building a Windows Phone 8.1 Silverlight App. I am able to use both the following registries:
Windows.Storage.ApplicationData.Current.LocalSettings;
IsolatedStorageSettings.ApplicationSettings;
What are the differeces between these two?
Which one is better?

The difference between Windows.Storage.ApplicationData.Current.LocalSettings and IsolatedStorageSettings.ApplicationSettingsis that the first one is the newer unified Windows Store App API whereas the latter is from the "old" Silverlight API.
New is not always better but I personally think you should go with the modern version here. Both work with Silverlight but if you ever have to migrate your code to WinRT you will save yourself some time since the IsolatedStorageSettings API does not work under WinRT.

There is huge difference in using both settings:
IsolatedStorageSettings works like a Dictionary and it's serialized and saved to IsolatedStorageFile:
IsolatedStorageSettings provide a convenient way to store user specific data as key-value pairs in a local IsolatedStorageFile.
Also note that IsolatedStorageSettings has to be saved - IsolatedStorageSettings.Save. After saving you will find a file __ApplicationSettings in your app's isolated storage.
ApplicationData.LocalSettings is an ApplicationDataContainer. Once you add there a value, it's automatically saved. It's model is conceptually equivalent to the Windows registry.
So they are totally different thing, and if you add key to one of above Settings then it won't appear automatically in second. Consider two buttons:
const string firstKey = "firstKey";
const string secondKey = "secondKey";
IsolatedStorageSettings isoSetting = IsolatedStorageSettings.ApplicationSettings;
ApplicationDataContainer localSetting = ApplicationData.Current.LocalSettings;
private void Button_Click(object sender, RoutedEventArgs e)
{
isoSetting.Add(firstKey, true);
localSetting.Values[secondKey] = false;
//isoSetting.Save(); // IsolatedStorageSettings have to be saved
Debug.WriteLine("Is first key in LocalSettings: {0}", localSetting.Values.ContainsKey(firstKey));
Debug.WriteLine("Is first key in ApplicationSettings: {0}", isoSetting.Contains(firstKey));
Debug.WriteLine("Is second key in LocalSettings: {0}", localSetting.Values.ContainsKey(secondKey));
Debug.WriteLine("Is second key in ApplicationSettings: {0}", isoSetting.Contains(secondKey));
}
private void Button_Click2(object sender, RoutedEventArgs e)
{
// run this button after app restart without clicking first button
// and saving IsoSettings
Debug.WriteLine("Is first key in LocalSettings: {0}", localSetting.Values.ContainsKey(firstKey));
Debug.WriteLine("Is first key in ApplicationSettings: {0}", isoSetting.Contains(firstKey));
Debug.WriteLine("Is second key in LocalSettings: {0}", localSetting.Values.ContainsKey(secondKey));
Debug.WriteLine("Is second key in ApplicationSettings: {0}", isoSetting.Contains(secondKey));
}
If I were writing a new app, then I would use new ApplicationData.LocalSettings API - it's newer and it will be much easier to port such an app to RunTime in the future, as WP8.1 RT doesn't support IsolatedStorageSettings.

Related

Trigger a phone call in Windows Phone 8 application

I need to develop an app to make a call from the Windows Phone 8 app using Visual Studio.
But I couldn't find any resources to do it.
When a button is clicked I need to call to a mobile number which is already given.
By clicking that button I must call only to that mobile number.
This is what I coded. When a given button is clicked, I this method is calling...
private void HyperlinkButton_Click_1(object sender, RoutedEventArgs e)
{
PhoneCallTask phoneCallTask = new PhoneCallTask();
phoneCallTask.PhoneNumber = "0719957868";
phoneCallTask.DisplayName = "Gage";
phoneCallTask.Show();
}
But I get an unhandled exception.
Unhandled exception.
// Code to execute on Unhandled Exceptions
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
Debugger.Break();
}
}
When you use PhoneCallTask, you have to specify a new Capability of your app in WMAppManifest.xaml: ID_CAP_PHONEDIALER
source
This is how you should do it:
PhoneCallTask phoneCallTask = new PhoneCallTask();
phoneCallTask.PhoneNumber = "2065550123";
phoneCallTask.DisplayName = "Gage";
phoneCallTask.Show();
Remember that the call is not automatically started but it prompts the user to confirm that action.
Here is how to initiate a call on windows phone
http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394025(v=vs.105).aspx
Ok for future reference i must add this.
If you get an Unauthorized Access Exception then you need to enable ID_CAP_PHONEDAILER from the Capabilities section in the WMAppManifest.xml file.
See here

Using a ToggleSwitch in App Settings

I want to use ToggleSwitch in the app settings. I am not able to save its state on IsolatedStorage so that it can be reflected on the MainPage. I have tried using the available Key/Value pair storage examples on msdn to perform this but have not been able to. Please write a precise solution if anyone knows.
Here you go:
in your settings page XAML
<toolkit:ToggleSwitch Header="Push Notifications"
Checked="PushNotificationsToggle_Checked" Unchecked="PushNotificationsToggle_Unchecked">
</toolkit:ToggleSwitch>
in your settings page code behind
private void PushNotificationsToggle_Unchecked(object sender, RoutedEventArgs e)
{
var settings = IsolatedStorageSettings.ApplicationSettings;
settings["PushNotifications"] = false;
settings.Save();
}
in your main page you can use this setting like this
var settings = IsolatedStorageSettings.ApplicationSettings;
Boolean usePushNotifications = (Boolean)settings["PushNotifications"]

how can i set the selectedIndex in a listPicker which i retrieve for isolatedStorageSettings in windows phone 8

I am developing a windows phone 8 app in which i have to use listPicker control. I need to save the selectedIndex from selected item in listPicker, in isolatedStorageSettings to be able to use it when the app opens. I want the saved index to be the selected index in my listPicker when the apps runs again. I have tried to do this with the onnavigatedto and onnavigatedfrom methods in the page in which i have the control. The problem is when i change se selected item and return back from full mode, the selected item does not change. I had searched this problem heare again and i didn't found the solution yet. How can i solve it?
Sorry for my English
I followed this settings_sample for the general setup by modifying the ListBox example. I ran into several problems trying to use a ListPicker with isolated storage like this.
http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff769510(v=vs.105).aspx
I removed the databindings for the ListPicker, set the SelectedIndex after initializing, and stored the SelectedIndex in isolated storage on SelectionChanged after the first occurrence of loading the page. It's a roundabout solution, but my searches came up empty.
public List<string> daysOfWeek = new List<string>() { "Sunday", "Monday", "etc" };
public int listPickerCounter = 0;
public Settings()
{
InitializeComponent();
BuildLocalizedApplicationBar();
// Fill listPicker with string items
this.listPicker.ItemsSource = daysOfWeek;
// Set SelectedIndex = IsolatedStorage Variable
if (IsolatedStorageSettings.ApplicationSettings.Contains("ListPickerSetting"))
{
this.listPicker.SelectedIndex = (int)IsolatedStorageSettings.ApplicationSettings["ListPickerSetting"];
}
}
On SelectionChanged update the isolated storage after the first occurrence of loading page.
private void listPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (listPickerCounter > 0 && IsolatedStorageSettings.ApplicationSettings.Contains("ListPickerSetting"))
{
IsolatedStorageSettings.ApplicationSettings["ListPickerSetting"] = (int)this.listPicker.SelectedIndex;
}
listPickerCounter++;
}
Edit: forgot to add another reference that really helped understand isolated storage.
http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj714090(v=vs.105).aspx

How to do CreateBindingSet() on Windows Phone?

In the N+1 video #34 (Progress), there was an example of using CreateBindingSet() for the Android version, which is not typical. But the narrator also mentioned briefly that the same can be done on the Windows platform.
As much as I tried, however, I am unable to get a View's property to be bound to its ModelView on the Windows Phone. I always get a NullReferenceException.
The closest I came was the code below, including suggestions from ReSharper. Here's my FirstView.xaml.cs:
using Cirrious.MvvmCross.Binding.BindingContext;
using Whatever.ViewModels;
namespace Whatever {
// inheriting from IMvxBindingContextOwner was suggested by ReSharper also
public partial class FirstView : BaseView, IMvxBindingContextOwner {
public class MyBindableMediaElement
{
private string _theMediaSource = "whatever";
public string TheMediaSource
{
get
{
return _theMediaSource;
}
set
{
_theMediaSource = value;
}
}
}
public FirstView()
{
InitializeComponent();
_mediaElement = new MyBindableMediaElement(this.theMediaElement);
var set = this.CreateBindingSet<FirstView, FirstViewModel>();
// the corresponding view model has a .SongToPlay property with get/set defined
set.Bind(_mediaElement).For(v => v.TheMediaSource).To(vm => vm.SongToPlay);
set.Apply();
}
public IMvxBindingContext BindingContext { get; set; } // this was suggested by ReSharper
}
I get a NullReferenceException in MvxBaseFluentBindingDescription.cs as soon as the view is created. The exact location is below:
protected static string TargetPropertyName(Expression<Func<TTarget, object>> targetPropertyPath)
{
var parser = MvxBindingSingletonCache.Instance.PropertyExpressionParser; // <----- exception here**
var targetPropertyName = parser.Parse(targetPropertyPath).Print();
return targetPropertyName;
}
I have not seen a working example of creating a binding set on a Windows Phone emulator. Has anyone gotten this to work? Thanks.
I can confirm that the narrator said that remark a little too flippantly without actually thinking about how he might do it...
However, with a little effort, you definitely can get the CreateBindingSet to work in Windows if you want to.
Before you start, do consider some alternatives - in particular, I suspect most people will use either Windows DependencyProperty binding or some hand-crafted code-behind with a PropertyChanged event subscription.
If you do want to add CreateBindingSet code to a Windows project then:
Add the Binding and BindingEx assemblies to your Ui project - the easiest way to do this is using nuget to add the BindingEx package.
In your Setup class, override InitializeLastChance and use this opportunity to create a MvxWindowsBindingBuilder instance and to call DoRegistration on that builder. Both these first two steps are covered in the n=35 Tibet binding video - and it's this second step that will initialise the binding framework and help you get past your current 'NullReferenceException' (for the code, see BindMe.Store/Setup.cs)
In your view, you'll need to implement the IMvxBindingContextOwner interface and you'll need to ensure the binding context gets created. You should be able to do this as simply as BindingContext = new MvxBindingContext();
In your view, you'll need to make sure the binding context is given the same DataContext (view model) as the windows DataContext. For a Phone Page, the easiest way to do this is probably just to add BindingContext.DataContext = this.ViewModel; to the end of your phone page's OnNavigatedTo method. Both steps 3 and 4 could go in your BaseView if you intend to use Mvx Binding in other classes too.
With this done, you should be able to use the CreateBindingSet code - although do make sure that all binding is done after the new MvxBindingContext() has been created.
I've not got a windows machine with me right now so I'm afraid this answer code comes untested - please do post again if it does or doesn't work.
I can confirm it works almost perfectly; the only problem is, there are no defaults register, so one has to do the full binding like:
set.Bind(PageText).For(c => c.Text).To(vm => vm.Contents.PageText).OneTime();
to fix this, instead of registering MvxWindowsBindingBuilder, I am registering the following class. Note: I have just created this class, and needs testing.
public class UpdatedMvxWindowsBindingBuilder : MvxWindowsBindingBuilder
{
protected override void FillDefaultBindingNames(IMvxBindingNameRegistry registry)
{
base.FillDefaultBindingNames(registry);
registry.AddOrOverwrite(typeof(Button), "Command");
registry.AddOrOverwrite(typeof(HyperlinkButton), "Command");
//registry.AddOrOverwrite(typeof(UIBarButtonItem), "Clicked");
//registry.AddOrOverwrite(typeof(UISearchBar), "Text");
//registry.AddOrOverwrite(typeof(UITextField), "Text");
registry.AddOrOverwrite(typeof(TextBlock), "Text");
//registry.AddOrOverwrite(typeof(UILabel), "Text");
//registry.AddOrOverwrite(typeof(MvxCollectionViewSource), "ItemsSource");
//registry.AddOrOverwrite(typeof(MvxTableViewSource), "ItemsSource");
//registry.AddOrOverwrite(typeof(MvxImageView), "ImageUrl");
//registry.AddOrOverwrite(typeof(UIImageView), "Image");
//registry.AddOrOverwrite(typeof(UIDatePicker), "Date");
//registry.AddOrOverwrite(typeof(UISlider), "Value");
//registry.AddOrOverwrite(typeof(UISwitch), "On");
//registry.AddOrOverwrite(typeof(UIProgressView), "Progress");
//registry.AddOrOverwrite(typeof(IMvxImageHelper<UIImage>), "ImageUrl");
//registry.AddOrOverwrite(typeof(MvxImageViewLoader), "ImageUrl");
//if (_fillBindingNamesAction != null)
// _fillBindingNamesAction(registry);
}
}
This is a skeleton from Touch binding, and so far I have only updated three controls to test out (Button, HyperButton and TextBlock)

RootFrame UriMapper for Caliburn Micro

I have been googling on how to actually implement this with no avail. Could not find a single resource on how to actually do it using Caliburn Micro.
Basically, I am trying this http://www.developer.nokia.com/Community/Wiki/OAuth_on_Windows_Phone
In the example, it used redirect_uri as normal link. I did it with Protocol/File Association (refer http://www.developer.nokia.com/Community/Wiki/URI_associations_for_Windows_Phone_8). Everything works fine. I got it to work without Caliburn Micro.
But based on that example, I would require to implement UriMapperBase and assigned it to RootFrame.UriMapper.
My question is how do I actually implement UriMapper with CaliburnMicro for WP8. For Win 8, it is different as I could override the OnActivate and check for the ActivationKind.Protocol and there is no need for UriMapper.
Ok. Finally managed to get it to work. So, will post it here because I'm pretty sure there will be a lost soul again like me who will appreciate the answer to this.
To use UriMapper in Caliburn, you will need to override the CreatePhoneApplicationFrame in the bootsrapper.
In Boostrapper.cs
protected override PhoneApplicationFrame CreatePhoneApplicationFrame()
{
// var frame = base.CreatePhoneApplicationFrame(); this doesnt work
var frame = new PhoneApplicationFrame(); // this works
frame.UriMapper = new AssociationUriMapper();
return frame;
}
AssociationUriMapper.cs - I just followed the example as per links above
public class AssociationUriMapper : UriMapperBase
{
private string tempUri;
public override Uri MapUri(Uri uri)
{
tempUri = System.Net.HttpUtility.UrlDecode(uri.ToString());
// URI association launch for contoso.
if (tempUri.Contains("pocketthis:MainPage"))
{
// Get the category ID (after "CategoryID=").
//int categoryIdIndex = tempUri.IndexOf("CategoryID=") + 11;
//string categoryId = tempUri.Substring(categoryIdIndex);
// Views/MainPage.xaml returns external exception,
// so remember the / before views
return new Uri("/Views/MainPage.xaml", UriKind.Relative);
}
// Otherwise perform normal launch.
return uri;
}
}
Hope this will help anyone trying to implement Uri/File Association in WP8 with Caliburn Micro.