Hybrid apps (apps that include native content and web content) are becoming more popular by the day. One question that naturally follows development of a hybrid app is “What’s the agent string so I can track it?”
Unfortunately there isn’t as simple one line answer to this question because of the way our platform has evolved over time. On the phone, for example, we send manufacturer and model information about the device in use. But beyond hardware we’ve also had an evolution in development platforms. At our //Build conference this year we announced the new Universal App model, which more or less allows you to run Windows 8 apps on your phone. In most cases this supersedes the classic Silverlight model but we still need to let web sites know the environment they’re running in so that they can tailor their experience accordingly.
Below is a list of agent strings for our current OS’s and dev platforms as of 5/14/2014. When this changes in the future I’ll try to come back and update this post. I’ve highlighted the changes in the agent strings for each scenario as compared to the “traiditional” mode for that platform. Below the agent strings you’ll find more notes about special cases and I even include bonus information at the end on how to test your site for Windows Phone using only your desktop browser!
IE Traditional (Desktop) Mode
Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko
IE in "Modern" Mode
Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; Touch; rv:11.0) like Gecko
Universal App WebView (C#)
Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; WebView/2.0; rv:11.0) like Gecko
Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; Touch; MSAppHost/2.0; rv:11.0) like Gecko
Windows Phone 8.1
IE in Traditional (Mobile) Mode
Mozilla/5.0 (Windows Phone 8.1; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; <manufacturer>; <model>) like Gecko
IE in Desktop Mode
Mozilla/5.0 (Windows NT 6.2; ARM; Trident/7.0; Touch; rv:11.0; WPDesktop; <manufacturer>; <model>) like Gecko
Universal App WebView (C#)
Mozilla/5.0 (Windows Phone 8.1; ARM; Trident/7.0; Touch; WebView/2.0; rv:11.0; IEMobile/11.0; <manufacturer>; <model>) like Gecko
Mozilla/5.0 (Windows Phone 8.1; ARM; Trident/7.0; Touch; MSAppHost/2.0; rv:11.0; IEMobile/11.0; <manufacturer>; <model>) like Gecko
Silverlight App WebBrowser
Mozilla/5.0 (Windows Phone 8.1; ARM; Trident/7.0; Touch; rv:11.0; WebBrowser/8.1; IEMobile/11.0; <manufacturer>; <model>) like Gecko
Desktop Mode for IE on Phone
IE on Windows Phone has an option to render sites as the desktop version under settings.
Many users prefer this mode, especially users with larger screens.
These are new to Windows Phone 8.1. Going forward, this is the mode that most developers will chose to use. Silverlight is the "classic" model in use today.
Simulating IE for Windows Phone on the Desktop
IE 11 and 12 on the desktop have the ability to simulate IE for Windows Phone pretty closely. To simulate Windows Phone IE (and use the desktop debugging tools in all their glory):
- Start IE
- Press F12
- Scroll down to the last tab in the dark bar on the left (Emulation) and set:
- Document Mode: 10
- Browser profile: Windows Phone
- User Agent String: IE10 – Windows Phone
- Orientation: Portrait
Note: These options will change going forward as IE for phone moves up in version numbers.
So Windows Phone has an integrated wallet experience, but why would you want to link it to your app? Well if you’re a financial institution of course you might want to enable payments with your cards. But even if you’re not a bank and your app offers deals, coupons, a membership or even stored value, integrating with the wallet give the user increased visibility to your offers. Oh, and did I mention free promotion in the wallet app – even if your app isn’t installed?
Adding Wallet support is actually quite easy, especially if the app doesn’t need to update the wallet when it’s not running.
The first step is to add the wallet capability to the app. This can be done by double-clicking on WMAppManifest.xml (under Properties), switching to the Capabilities tab and checking the ID_CAP_WALLET checkbox.
Don’t check the other two wallet-related boxes unless you want to add real payment options (e.g. Visa credit cards) that can be used to buy music, apps, etc. These boxes don’t need to be checked for membership cards (like a Starbucks card).
Note: If a financial app does want to add payment cards it will need to pass a few extra certification requirements with the Windows Phone store.
Next we need to register our app as an extension to the wallet. Unfortunately there isn’t a way to do this in the UI so we’ll need to save our work, right click on WMAppManifest.xml and choose ‘View Code’. After the closing </Tokens> tag, add an Extensions block like this:
ConsumerID and TaskID will never change – they’re always those values. But ExtensionName might change depending on how you want to interact with the wallet. The choices are:
- Wallet_app_other – for non-specific Wallet items
- Wallet_app_loyalty – for loyalty cards
- Wallet_app_membership – for membership cards
- Wallet_app_transit – for transit cards
- Wallet_app_payment – for payment cards
Wallet_app_membership is a good choice for most applications, and if you want to register support multiple extensions you could do it like this:
Now save WMAppManifest.xml and when you submit your app to the store it will start getting promoted in the wallet app. That’s a tremendous advertising advantage!
The last thing we need to do is have our application add a card to the wallet. Up to this point we’ve given the app the ability to interact with the wallet and gotten our application advertised there, but there’s still no link from the wallet back into our app once it’s installed. Don’t worry, the card you create can simply be a membership card. It doesn’t have to report a live credit balance (though it can if you want it to). You might just want to display a logo and give the user the ability to launch the app. Of course this is a great place to add customer support information like e-mail addresses and phone numbers, and you might want to display a QR code for example to identify the user at a retail store. It’s up to you how much information you want to add, but the WalletTransactionItem documentation gives you a listing of what’s possible.
When your app adds the card is up to you, but a good place to ask is on application launch. Of course if the user declines the card we don’t want to ask again (though we probably want to give them the option to add it later via a button or menu item). Also keep in mind that the membership card might have already been added so we want to make sure it doesn’t exist before we try to add it again.
Finally, there are some slightly unusual requirements we need to knowing about the card logo image. First of all, the card actually needs three image sizes (336×336, 159×159 and 99×99). Luckily we can supply one large image for all three sizes and the system will resize it for us. The more important requirement is that the image has to be fully loaded before the request is made to add the card. Most people don’t know that passing a URI into the constructor of BitmapImage doesn’t load it right away. It kicks off a background task to load the image and you’ll get an exception if you try to add your card before this task completes.
There are a couple of workarounds but the easiest one is to store the image as a resource and load it as a stream. Don’t forget to set the Build Action in the property window to ‘Embedded Resource’ instead of ‘Content’, which is the default.
Here is one possible method for adding a membership card:
We also need the event handler for when the task completes. This is so we can inform the user if something went wrong and it’s also a good place to store a flag if the user chooses to decline the card:
Now we can call EnsureMembership from the page Loaded event or from a button click. In the loaded event we only want to call it automatically if the user hasn’t declined the card before.
And finally, we can call the same method from a button click without checking for a previous decline (since the user is actually making the request).
These are the basic steps needed for wallet integration and the sample code can be downloaded here. If you’d like to know more about the wallet like payment cards and updating the wallet in the background, I highly recommend this video on Channel 9.
The Problem with Ratings
It’s no secret that apps with higher ratings (and more of them) receive better placement in the store. Better placement means more downloads, and more downloads means more money. But part of the problem with ratings is that people rarely think about doing them. And when they do, it’s usually because they’re either really satisfied or really dissatisfied. InfoSurv, a company that provides market services to companies like CocaCola, Nestle and Emerson, has this to say in their FAQ:
There is a observed response bias in customer satisfaction surveys towards the customers on either extreme of the satisfaction scale, particularly those who are very dissatisfied. In other words, very satisfied or dissatisfied customers are more likely to respond to a survey invitation than those more towards the middle. The best way to combat the resulting “polarization” of customer survey data is to assure the maximum survey response rate possible, thus capturing more of the ambivalent customers and making the customer survey responses more representative of the overall customer base.
So as app developers we have to solve two problems: 1) Getting more users to rate our apps and 2) Finding happy customers.
Solving the Rating Problem
Obviously it doesn’t make sense to ask someone for a rating on the first application run – the user wouldn’t know what to say! On the other hand, if a user continues to use an app over time we can infer that they’re getting value out of the app. Therefore it’s repeat users who we want to ask for ratings.
With that in mind, a rating reminder should:
- Keep track of the number of times the application has been run. – It helps us find happy users.
- Keep track of whether the user has already been asked to rate the application. – So we don’t keep bugging them if they’ve already rated or said they don’t want to rate.
- Bonus: Keep track of the number of days since an application was installed. – Valuable for short-lived or seasonal applications. For example, a Christmas application might want to remind after two days regardless of usage since after December 25th they won’t use it again for a year.
- Bonus: Have the ability to display the reminder in the local language. – Important for applications that support multiple languages.
The code to implement these features isn’t overly complex but it does involve several components (storage, dialogs, marketplace APIs, localization, etc.). It’s also boilerplate – meaning it’s the same across applications. That makes it a great candidate for being factored into a library.
App Promo is a tiny control library for Windows Phone and Windows 8 created to help with promoting applications. Right now it contains one control – RateReminder – and by now you probably have a good idea of what it can do for you.
RateReminder has four main properties:
- RunsBeforeReminder – The number of application runs before the reminder will be displayed. The default is 7.
- DaysBeforeReminder – The number of days before the reminder will be displayed. The default is zero (disabled).
- TryReminderOnLoad – true if the control should try to show the reminder as soon as it’s loaded; otherwise false. The default is true.
- CustomReminderText – The customized reminder message to display to the user. The default is null (which means the control will use its built-in localized message).
As you can see, RateReminder is configurable but its default settings mean you can drop it on your main page and forget about it. And since App Promo is available as a NuGet package, there’s no reason not to add it to your app today!
Using App Promo
Let’s take a look at how to add App Promo to a project. I’ll be showing App Promo for Windows Phone, but the steps are the same for Windows 8 (just using a different NuGet package).
- Before we get started we need to make sure you have NuGet installed. In Visual Studio click on Tools –> Extensions and Updates. If you see NuGet in the list you’re already set. If not, type NuGet in the search box and install it (a restart of Visual Studio will be required).
- Next we need to install the App Promo NuGet package. You can do this through the Package Manager Console but I prefer to use the GUI. In Solution Explorer, right-click on your project and choose ‘Manage NuGet Packages’.
- Make sure the ‘Online’ branch is selected on the left and type ‘AppPromo’ (no spaces) in the search box.
- Click the ‘Install’ button next to App Promo for Windows Phone 8 (or for Windows 8 if you’re building a Windows 8 app) and when the installation completes, close the NuGet window.
- Expand the toolbox if it’s not already expanded, then right-click and select ‘Choose Items…’. In the window that pops up, click the ‘Browse’ button.
- Navigate to your project folder, then to packages –> AppPromo.WP8.#.#.#.# (or AppPromo.Win8.#.#.#.#) –> lib –> wp8 (or winrt45).
- Double-click on AppPromo.WP8.dll (or AppPromo.Win8.dll) and click OK. The RateReminder control should now appear in your toolbox.
- Drag the RateReminder control onto the first page of your application (this is usually MainPage.xaml or GroupedItemsPage.xaml).
NOTE: The RateReminder control is completely transparent and has no appearance. You’ll want to remember where you placed it or use Xaml view or Document Outline if you need to select it.
- Optional: Change the number of runs (default 7) or the number of days (default 0 – disabled).
- You’re done! You just added a rating reminder to your application.
NOTE: App Promo has been added to your project but NuGet can’t add the control to your toolbox. We need to do that before you can drop it on your page.
Testing the RateReminder Control
Testing the RateReminder control is easy. Just remember that the application has to be closed and re-launched in order to be considered a “run” (otherwise the user is just fast switching). In Visual Studio you can quickly simulate a close and a re-launch using the Restart button:
If you don’t have Visual Studio attached you can use the phones hardware Back button to leave the app and then launch it again. For Windows 8, use the Reset button above or drag the window to the bottom of the screen to close the app between runs.
Important Note!: On Windows 8.1 apps are not actually closed unless you hold them at the bottom of the screen until they flip over (about 3 seconds).
After 7 runs (or however many you configured), the rating reminder will be shown:
Tapping OK will display the rating page if the application is already in the store. Otherwise, you’ll see an error message telling you that the application is not currently available.
RateReminder provides a small amount of usage statistics through the TryReminderCompleted event (if run automatically on load) or through the asynchronous result returned from TryReminder (if called manually). Both return an instance of the RateReminderResult class, which provides the following usage statistics:
- Runs – The number of times the application has been run since it was installed. This count is only calculated if the runs reminder is enabled and hasn’t already been shown.
- Days – The number of days that have passed since the app was installed. This count is only calculated if the days reminder is enabled and hasn’t already been shown.
- ReminderShown – true if a reminder was shown on this attempt.
- RatingShown – true if the user accepted the reminder and the rating interface was shown on this attempt.
The source code includes a sample that displays usage statistics. It’s important to note that the counter will read zero after the reminder has been shown. This is to avoid the cost of reading and updating settings after the reminder has been displayed.
The counters can be reset by calling the ResetCounters method on the RateReminder control. This will cause the reminder to be displayed again, which may be desirable after the application has been upgraded to a new version.
App Promo has been translated into more than 35 different languages, but it’s important to know that your app must also be localized for these languages to be shown. This is because the resource loader tries to be as efficient as possible. For example, when your application is run on a device set to Spanish, the resource loader will look for Spanish resources in your application. If it doesn’t find them, it won’t continue to look for Spanish resources when it loads the App Promo library.
Localizing your application is beyond the scope of this article, but as soon as your app is localized App Promo will show up as localized too. By far the easiest way to localize your application is using the Multilangual App Toolkit. This article is one of the best written guides I’ve found, and the Introduction and Testing videos are both excellent resources for getting started quickly.
The source code for App Promo is available on on GitHub and includes two sample applications. Don’t forget that App Promo is already ready-to-use on NuGet. Here are direct links to the Windows 8 and Windows Phone 8 packages.
I’d like to extend a special “Thank You” to my co-worker and friend Paul DeCarlo. Paul created the NuGet packages for App Promo and he’s got a lot of experience when it comes to marketing Windows Phone and Windows 8 apps. I highly recommend you check out his blog post on Monetizing your app with AdRotator.
From the app description:
"App Enthusiasts showcases applications created by developers around the world on Windows Phone and Windows 8. Stay up to date with the coolest creations by students, indie developers, and companies in your area. App Enthusiasts can filter apps by region, country, state and city, and it even keeps track of the apps you’ve seen across all of your devices! Microsoft employees are using App Enthusiasts to showcase apps at local events around the world, so if you’re interested in having your application promoted or if you’d like to find out about Enthusiast events in your area, please email AppEnthusiasts@Microsoft.com."
What is exciting is that App Enthusiasts is more than just an app, it is a movement to bring visibility to applications created by Windows Phone and Windows 8 devs. Microsoft field employees are planning to host events at Microsoft retail stores across the U.S. At these events, developers featured in App Enthusiasts share their creations and speak to the audience about their inspiration. We believe that an application like this can help create a community of supportive developers and fan interest alike. I certainly suggest reaching out to AppEnthusiasts@Microsoft.com if you have an app that you would like featured in this program! Seriously, we want your best work to shine!
Let’s take a look at the app itself:
Upon launching either version of the app, the user is asked to authenticate with their Live credentials and is then greeted with a listing of applications organized by date:
Users can see at a glance what City, State, and Country an app has been published in. Upon clicking an item, the user will be brought to the download page in the marketplace for the selected app. When an item has been viewed, a checkmark appears next to the item indicating that it has been seen.
With these applications it’s really easy to discover cool apps from my region. By setting the filter to my city I was able to see creations from people in my area. From here I could easily install apps built by people I’ve actually met in the field. Being able to curate and find their work made it incredibly easy for me to provide feedback and ratings. It is a really great way for me to keep in touch with my community and help promote the Windows ecosystem. If you want to know more about the upcoming events and how to showcase your app, send an e-mail to AppEnthusiasts@Microsoft.com.
Apps can specify that they prefer portrait or prefer landscape in their appxmanifest by checking one or more boxes:
However, the app is not guaranteed to get the preferred orientation. The classic example is a game that requests portrait but is being run on a desktop machine with a monitor that cannot be rotated. The game will be forced to run in landscape instead and it’s up to the game to deal with this (e.g. letterboxing or putting content on the sides of the otherwise vertically laid out game).
At //build it was clearly stated that with 8.1 and the smaller 7” devices, most users prefer to hold the device in portrait. Of course in this scenario the device is portable and the OS knows that the device can be rotated, so if an app requests to run in landscape the OS would honor it. But be aware that it’s still possible for an app to get locked in portrait too. It’s less common but can happen. On my old desktop rig I ran dual 27” monitors where one was landscape and the other was portrait. On that machine if I ran store apps on the portrait monitor, the OS would force them to run in portrait.
In summary, you can ask for whatever orientation you want but be prepared not to get it.
For more information see the InitialRotationPreference element.
Just wanted to share my notes from day 1 at //build.
8.1 OS Beta Available
One of the biggest announcements was the preview of Windows 8.1 which you can download at http://preview.windows.com. It comes down to your machine as a KB patch that enables the update to show up in the store app on your device. You actually download and install the app through the Store. This is the first time I’m aware of that we’ve distributed an OS-level update through the store.
The update is about 2.1 GB and you can continue using the operating system while the update downloads in the background. Once the download is complete you’ll be prompted to reboot. The machine goes through several phases during the boot screen with the spinning white doughnut. The actual upgrade process takes a good 10 minutes after the download is completed (at least that’s how long it took on my Surface RT).
After the upgrade is complete you will have to go through the out of box experience again, including associating your device with a Microsoft account. But your data is still there and your apps are still installed. There is no way to revert to Windows 8.0, but the installer claims you will be able to upgrade to the final version of 8.1 when it becomes available.
The OS received 800 major features and the Windows Runtime received over 5,000 new APIs. These include things like bar code scanning, Bluetooth RFCOMM support and a lot more. I did see a lot of these demonstrated today and they didn’t feel like 5,000 new APIs. I wonder if this number includes the new Bing platform APIs (more below).
Apps appear to be much more tightly integrated. A demo showed going from Bing to Weather to Maps to OpenTable. Another demo showed going from a website with various artists to a playlist in XBOX Music. I’m hoping the session Building Apps that Work Together will provide more information.
Sprint finally has a good lineup of Windows Phones coming. The HTC 8XT looks similar to the 8X on AT&T and Verizon. They also have the ATIV S. With Sprint on board we can now claim all major US carriers have support for Windows Phone.
Bing as a Platform
To me, by far the biggest announcement in the keynote was Bing as a platform. This ‘platform’ is delivered as a set of controls that developers can just plug into their applications. Two of the most powerful demonstrated was the new map control with full 3D support and optical character recognition with language translation.
The map was beautiful and seemed to be even higher quality than the Nokia Here 3D stuff I was raving about a few weeks back. It even apparently supports scripting of the camera location and direction and does smooth animating between points. This was demonstrated with a virtual tour.
The OCR demo showed the user ‘scanning’ a business card in another language with the camera. The text was recognized and each word was framed in a border. Then with a touch, the card was translated into English in real time. Impressive stuff.
They closed with an updated live demo of Project Spark. I just cannot express how excited I am about this platform / game and when I got to play with it at lunch it blew me away. Multi-touch was just as fluid as could be on the 80” PixelSense screen. We created a few different games on the fly and folks from the product team were on hand to answer tons of questions. Of course it’s already been announced that we’re giving the game away for free, but I got confirmation that there will be new characters and add-ons for purchase. When asked if ‘players’ will be able to profit from their creations, the answer was ‘we have nothing to announce on that at this time’. Another attendee asked how it would be possible to import our own custom objects into the game, from, say 3D Studio. His answer was “We have nothing to announce regarding 3rd party partnerships at this time.” Telling, I think. Exciting for sure.
I was really glad to hear one of the first things they mentioned in this session, which is that they’ve put a bunch of work into improving performance in XAML for 8.1. Not that XAML had terrible performance issues in 8.0, I’m just really glad to see the team continue to invest engineering effort into the XAML UI technology.
A number of new controls were demoed, but probably the most important one is the HubView. We finally have a very prescriptive way of creating the fairly standard “Home” page for many Windows 8 applications.
There’s an update to WebView that allows it to correctly play in screen compositing (previously it only displayed on the top of the Z-Order, so flyouts and things were drawn under it. That’s been fixed. And we now have the ability to put islands of WebGL content in even our XAML apps if we wanted to.
There’s an interesting new option for writing apps that directly support dual screen systems. So, for example, you could have an app where a cashier sees one thing and a customer sees another but it’s all just a single app.
Speaking of Point of Sale, we now have native APIs for barcode readers and mag stripe readers. The mag stripe reader is obviously a sensitive resource. You don’t want another app stealing it away from you when the user is about to swipe their credit card. The device is actually shared across apps, but apps have the ability to capture it and hold onto it during critical times. It’s an interesting API.
There’s a new HttpClient. It looks just like the .Net HttpClient but it’s a WinRT component so it can be used in C++ and WinJS applications now as well.
They demonstrated speech synthesis. The API looks similar to the API on Windows Phone in that you create a synthesizer and tell it to SynthesizeText. What was interesting in the demo is that the text was synthesized to a stream. They then played the stream in a MediaElement but they also said it could be saved to a file or stored in the cloud. One of the things I thought was interesting is that because it’s played through a standard MediaElement it could also be “remoted” via PlayTo.
Finally, they attempted to demonstrate Bluetooth but the demo failed. They were going to control a Sphero robot but they couldn’t get it to pair.
In this session I was hoping to see a lot of code and demos on connecting to various devices, but it was more of an overview about what’s possible. With 8.1 now supports the following:
· Fingerprint readers
· Barcode readers
· Mag stripe (credit card) readers
· Geofencing (trigger when the user enters or leaves an area)
· Virtual Smart Cards
· 3D Printing
· Image Scanning
In addition to “well-defined” interfaces for known devices, 8.1 also adds support for “custom” devices by supporting industry standard protocols like
· Bluetooth RFCOMM
· Bluetooth Smart / Low Power
· Wi-Fi Direct
This mode of talking to a device is analogous to opening a socket or a serial port and sending bytes. You have to know what packets the device is expecting (i.e. the “shape” of the data) and then you can communicate. They encouraged device developers to wrap protocols into WinRT components so that they’re easier for application developers to consume.
There is also now an official process that hardware manufacturers can go through so that the first time a user plugs in a device, Windows will download and launch the companion application. This is all hooked through the Auto Run infrastructure and the device manufacture has to go through an extra registration process, but it looks pretty cool.
Applications now have a new trigger that they can run on when they’re associated with a device. Applications that run on the custom device trigger can run for up to 10 minutes in the background, allowing for things like data sync or even potentially firmware updates while the app is not in the foreground.
In the end I felt like I would have better benefitted from attending one of the more in-depth sessions like Apps for Bluetooth, HID and USB Devices.
This was the last session I attended and it was mainly out of a curiosity I’ve had for a long time with Artificial Intelligence. The guy was from MS Research and he was pretty entertaining to listen to. He demystified some of the verbiage around the topic and tried to give the audience a kick start, but I still felt you needed to have some basic understanding of the subject matter to benefit from his talk. I was pretty disappointed that the title of his talk included the words “Using Visual Studio” and yet he spent less than 5 minutes running code and didn’t even explain how it worked.
Anyway, so far I’m having a great time and really looking forward to Day 2.
I’m working with a number of partners right now that want to target both Windows Phone and Windows 8 using a single codebase. This post is a copy of an e-mail I send to them when they’re getting ready to start development using Portable Class Libraries.
First, I’d like to share some libraries that I’ve found to be invaluable during PCL development:
First, I’d like to share some libraries that I’ve found to be invaluable during PCL development:
HttpClient for PCL
Windows 8 has the most advanced client for reading data from the web asynchronously. That client is called HttpClient. Unfortunately HttpClient doesn’t exist on Windows Phone, so the moment you check the box to include Windows Phone support in your PCL you lose the ability to leverage HttpClient and have to use the older WebClient. This library adds the awesome tool back into your PCL project.
MVVM Light PCL
MVVM Light is one of the most popular libraries for implementing the MVVM pattern on Windows Phone and Windows 8. Until recently they had one library for Windows Phone and another library for Windows 8. This made it impossible to create ViewModels in a PCL project. Now that they have a PCL library you can create all of your ViewModels in PCL and use them on both platforms. The only trick is make sure you reference the PCL version of this library in you Windows Phone and Windows 8 projects as well (not the platform-specific versions).
Finally, are PCLs the right approach for your project? Though I’m a fan of PCLs, I have found there are times when it takes more effort to work around the limitations of PCL than it does to just share (link) code across projects.
For example, let’s say you want to remember a setting between application runs. On Windows Phone you use a class called IsolatedStorageSettings and on Windows 8 you use ApplicationData.Current.LocalSettings. If you wanted to abstract this difference in a PCL you would have to create an interface (let’s call it ISettingManager) and inject that interface from the host application down into the PCL when the application starts up. This is called "Dependency Injection" and you can read more about this approach in Portable Class Libraries: A Primer.
Although dependency injection absolutely will solve this problem, it’s also somewhat complicated to implement. You have to define the interface, create two platform-specific implementations of the interface (one for WP and one for Win8) and then you have to remember to pass the implementation into the PCL on application start. It’s not rocket science, but it is a lot of effort to solve for such a minor difference.
Another approach is to link a .CS file into both projects and take advantage of conditional compile statements. Here’s a short article on conditional compilation in Visual Studio.
With this approach we could easily write the following class and use it in both projects:
static public class SettingManager
static public void SetValue(string name, string value)
var settings = ApplicationData.Current.LocalSettings;
settings.Values[name] = value;
var settings = IsolatedStorageSettings.ApplicationSettings;
settings[name] = value;
static public string GetValue(string name)
var settings = ApplicationData.Current.LocalSettings;
var settings = IsolatedStorageSettings.ApplicationSettings;
Notice that the compiler takes care of including the right lines of code for each platform. In my opinion this is a lot simpler than creating interfaces and dealing with dependency injection. However, if PCLs make sense for your project using shared files and conditional compilation can be very helpful when creating the interface implementations (wrappers).