WebAssembly in Action

Author of the book "WebAssembly in Action"
Save 40% with the code: ggallantbl
The book's original source code can be downloaded from the Manning website and GitHub. The GitHub repository includes an updated-code branch that has been adjusted to work with the latest version of Emscripten (currently version 3.1.44).
Showing posts with label Windows Store app. Show all posts
Showing posts with label Windows Store app. Show all posts

Tuesday, October 30, 2012

Windows 8: Windows Store apps - Privacy Policy


Over the past few articles, we've been talking about creating a Windows Store app. The following are the links to the articles if you're interested:


When I first submitted my app to the Windows Store it failed certification due to the Windows 8 app certification requirement 4.1: http://msdn.microsoft.com/en-us/library/windows/apps/hh694083.aspx

At the time, the 4.1 requirement wasn't entirely clear to me but, after some digging on the internet, I was able determine what was needed.

The good news about the certification requirement documentation is that it appears to be improved over time because section 4.1 is now a bit more clear as to what is needed.


The reason why my app failed certification was because any app that makes a connection to the internet, which our app does, can result in some of your user's personal information making it onto the internet (e.g. the IP address could be used to determine their location).

If you app has the ability to communicate over a network then you need to provide a privacy policy with your app via the Settings charm as well as a link to a web page for use in the Windows App Store gallery.

The privacy policy doesn't have to be legalese but does have to tell the user how their information is used, stored, secured, if it's disclosed with third parties, etc.

Since every app is different, the common recommendation is to go through the Windows Store apps looking at the various privacy policies to come up with one that best fits your app's functionality.


A download of the project (C# and built using Visual Studio Express 2012 for Windows 8) can be found in the following location:
https://github.com/downloads/dovicoapi/DOVICOTimerForWindowsStore/DOVICOTimerForWindowsStore.zip

Friday, September 21, 2012

Windows 8: Windows Store apps - JavaScript passing data to the code containing the WebView control


Over the past few weeks, in my spare time, I've been working on building a Windows Store app that will wrap an HTML web app that I've built.

To use the web app, you enter a token in a textbox on the welcome page and then click the Verify button.

If the token is valid, a URI is given to the user which can then be used for the tracking of one's time using the start/stop timer view in the web app.


The issue that we're going to tackle in this blog post is the following:

When the user clicks the Verify button on the welcome page and a URI is generated, I would like the JavaScript to call the code that holds the WebView control to have the URI saved.

This will save the user the trouble of having to copy the URI, open up the settings flyout, and paste in the new URI.


I know that the JavaScript, of a page loaded in a WebBrowser control, can talk to the C# code when the ObjectForScripting option is turned on but do we have access to a similar feature in a Windows Store app when using a WebView control?


ScriptNotify and AllowedScriptNotifyUris

As it turns out, it is possible for the JavaScript of a page loaded into a WebView control to call into the C# code of the page if you set up a ScriptNotify event.

According to the Microsoft documentation on the ScriptNotify event (http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.webview.scriptnotify), depending on which method you use to display the page in the WebView control, you may or may not have to specify URIs that are allowed to call the event handler.

If you use the WebView's Navigate method then you must specify the list of URIs that are allowed to call the ScriptNotify event handler.

If you use the WebView's NavigateToString method then the list of URIs is not necessary.


I've been simply setting the WebView's 'Source' property with the desired URI so the question is: Do I need to specify the list of URIs or not?

As it turns out, if I don't specify the list of URIs when using the WebView's Source property, the ScriptNotify event does not trigger.

You specify a list of allowed URIs in the following manner:
List<Uri> lstAllowedUris = new List<Uri>();
lstAllowedUris.Add(new Uri("http://apps.dovico.net"));
wvBrowser.AllowedScriptNotifyUris = lstAllowedUris;

Note: The property AllowedScriptNotifyUris almost suggests that you can say one page can make ScriptNotify event handler calls but none of the other pages on the site can.

In reality, based on my testing, even if you specify a URI to a particular page, any page within that domain can call the event handler.

The AllowedScriptNotifyUris property is really a list of allowed domains who's pages are allowed to call the ScriptNotify event handler.


The following is an example of how to wire up a ScriptNotify event handler:
public MainPage()
{
// Only allow the following domain's pages to call our ScriptNotify
// event handler
List<Uri> lstAllowedUris = new List<Uri>();
lstAllowedUris.Add(new Uri("http://apps.dovico.net"));
wvBrowser.AllowedScriptNotifyUris = lstAllowedUris;

// Attach our ScriptNotify event handler
wvBrowser.ScriptNotify += wvBrowser_ScriptNotify;
}

The following is an example of the event handler itself:
void wvBrowser_ScriptNotify(object sender, NotifyEventArgs e)
{
// The string received from the JavaScript code can be found
// in e.Value
}


On the JavaScript side of things, the code is similar to what you would write when calling the C# code of a WebBrowser control with the exception that the function you call is 'notify' where with a WebBrowser control you could define your own callback function name.

The following is an example of the JavaScript code that calls the C# code:
// We have a couple of checks to make sure the 'external'
// object and 'notify' method exist before we try using them
// because our project is a web application and might not be
// running in a WebView control (the checks prevent
// JavaScript errors if the method doesn't exist)
if ((typeof (window.external) !== "undefined") &&
(typeof (window.external.notify) !== "undefined"))
{
window.external.notify(sURI);
}



In Conclusion

Even though the JavaScript is only capable of passing a string to the ScriptNotify event handler, it is highly recommended that you verify the string is in the expected format before trying to use it even if the string came from a source you included in the list of allowed URIs.


Additional Resources

If you are interested in details on how to implement a Settings flyout, especially if you are using a WebView control, I have a previous article that might be of interest: Windows 8: Windows Store apps and the WebView control (we discussed how to display a Settings flyout and focused mostly around making the WebView control play nice with the flyout).

If you are interested in RoamingSettings and the DataChanged event, the following article might also be of interest: Windows 8: Windows Store apps - RoamingSettings and the DataChanged event


A download of the project (C# and built using Visual Studio Express 2012 for Windows 8) can be found in the following location:
https://github.com/downloads/dovicoapi/DOVICOTimerForWindowsStore/DOVICOTimerForWindowsStore.zip

Monday, September 17, 2012

Windows 8: Windows Store apps - RoamingSettings and the DataChanged event


In a previous article (Windows 8: Windows Store apps and the WebView control) we discussed how to display a Settings flyout and focused mostly around making the WebView control play nice with the flyout.

We created a Settings flyout because we want to store the URI that is used by the WebView control.

Now that we have the Settings flyout working, how do we store settings in a Windows Store app?


ApplicationData and RoamingSettings

It turns out that Windows Store apps have access to a class called ApplicationData which allows the storage of session state, user preferences, and other settings.

You have access to the following types of storage with the ApplicationData class:
  • local - persistent data but only on the current device
  • roaming - data that is available to all devices the user has your app installed on
  • temporary - data that can be removed by the system at any point after your app is closed

Local would do the trick but roaming caught my attention.

Being able to set a setting on one device and have all devices, that your app is installed on, automatically know about the new setting sounds pretty neat and would make things a lot easier for the user.


Setting a RoamingSettings key/value pair can be done as follows:
using Windows.Storage;

ApplicationData.Current.RoamingSettings.Values["URI"] = sURI;

Pulling a RoamingSettings value can be done as follows:
string sURI = ApplicationData.Current.RoamingSettings.Values["URI"] as string;
if (!string.IsNullOrWhiteSpace(sURI))
{
// do something with the setting
}


The DataChanged event

Another neat feature of the roaming settings is that you can subscribe to a DataChanged event so that your app can know when a setting was changed on another device.

One thing to be aware of here is that the DataChanged event might not fire at the instant that you set a RoamingSettings value. The synchronization of the roaming app data is controlled by Windows itself.

In our case passing the roaming settings data to other devices instantly is not a concern but what would be nice is if the Settings flyout changes would trigger the DataChanged event in the app where it was changed. As it turns out this is possible...

You can simulate a DataChanged event by calling the SignalDataChanged method after you apply the new settings and it will send a DataChanged event to all registered event handlers:
ApplicationData.Current.SignalDataChanged();


Handling the DataChanged event

Initially, I let Visual Studio wire up my DataChanged event handler (I typed in the += characters and pressed Tab) which gave me the following:
// Don't use this
ApplicationData.Current.DataChanged += DataChangedHandler;

When I ran the application, I discovered an issue where the event is being triggered, because my breakpoint was being hit, but the WebView control was not being updated with the new URI.

After some digging, I discovered that the MSDN documentation for implementing a DataChanged event handler uses the following method:
// Use this
ApplicationData.Current.DataChanged += new TypeEventHandler(DataChangedHandler);

Changing how the DataChanged event handler is registered didn't solve my issue of the WebView control not updating when the URI changes.


Background Threads and the UI Thread

As I was thinking about the issue a thought occurred to me...

Updating the WebView control would be the UI thread's responsibility.

What if the DataChanged event is being received on a background thread?

I've seen the code to call a UI thread in a developer training session at some point in the past (I think it was in regards to Silverlight but I'm not sure).

Either way, I thought I knew what the issue was but I couldn't remember how to get around it so I started searching the internet and I ran across the following MSDN sample code that had just the information I needed: http://code.msdn.microsoft.com/windowsapps/ApplicationData-sample-fb043eb2/sourcecode?fileId=43552&pathId=278302945

The following is the DataChanged event handler you need if you wish to update (directly or indirectly) the UI of your app since the DataChanged event might be triggered on a background thread which has no access to the UI:
async void Current_DataChanged(ApplicationData sender, object args)
{
// DataChangeHandler may be invoked on a background thread, so
// use the Dispatcher to invoke the UI-related code on the UI
// thread.
await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// Cause the web browser to reload in its content
UpdateURI();
});
}



In Conclusion

Overall, RoamingSettings in Windows Store apps are pretty straightforward.

One thing to remember with the DataChanged event, if you need to update the UI (directly or indirectly), is that the event might arrive on a background thread and you will need to dispatch the call to the UI thread.


Additional Resources

The following are some additional resources with regards to ApplicationData and RoamingSettings:
A download of the project (C# and built using Visual Studio Express 2012 for Windows 8) can be found in the following location:
https://github.com/downloads/dovicoapi/DOVICOTimerForWindowsStore/DOVICOTimerForWindowsStore.zip