Migrating from PCLStorage to .NET Standard 2.0

If you’re a Xamarin Forms developer, you’ve likely used PCLStorage (or other Dependency Service) to interact with the target platform’s file system in the portable class library’s code. However, since November 2017, Xamarin.Forms now uses a .NET Standard 2.0 class library and PCLStorage is no longer supported.

System.IO.File

This isn’t a problem because in .NET Core 2.0 you now have access to System.IO.File’s GetFolderPath and SpecialFolder methods (see System.IO.File in .NET Core 2.0 docs).

Thus, you can get a path to the app’s local folder (the one that the app can save to) without having to write a Dependency Service (which is what PCLStorage does) by using:

var localFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

 

IMPORTANT: Make sure you always use Path.Combine to create the file path because different platforms use different path separators

var filePath = Path.Combine(LocalFolder, "notes.txt");

 

With a reference to the file path,  you can now access the file. For example reading the text:

var notes = File.ReadAllText(filePath);

Functional Demo

As a very simple example, I created a couple extension methods for Stream and Byte[] in the below FileExtensions class.

To test it, I created a ContentPage that downloads an image, saves it using the extension method and set a FileImageSource to confirm that it’s a file (instead of just using a StreamImageSource).

 

https://gist.github.com/LanceMcCarthy/693ab82aa498cadf75e9fe778c4242ad

 

Note that the extension methods are very basic and shouldn’t be used in production as-is (i.e. no defensive programming code).

Here is the result at runtime on UWP:

2018-04-19_1134

Denied?

So, you got an email from DVLUP stating that your challenge submission was denied.  Why were you denied? What did you miss?  I wanted to write this post to share the top reasons for denial and how to fix it… 90% of these are due to the fact you didn’t edit your WMAppManifest file.

Here are the top offenders:

  • Not all Live Tiles Sizes
  • No animated Tiles
  • Not all WP8 resolutions

#1- You need to have all three tile sizes enabled for your app. Here is a list of the tile sizes from the MSDN Documentation. To rectify this problem, simply toggle the “Support for large Tiles” property in your WMAppManifest file. See the image in answer #2 for more details.

Tile Sizes

#2- Your app failed because the tiles were static. You need to bring your pinned tiles to life with one of the tile templates. Below is an example, find more here in the MSDN Documentation:

Cyclic Template– This template rotates between 1 to 9 images for your pinned tile. To meet the challenge’s requirement you need to have at least 2 images. Here is a quick and easy way to setup a tile from an event handler:


CycleTileData cycleTile = new CycleTileData()
{
Title = "DVLUP Rules";
Count = 2;
SmallBackgroundImage = new Uri("/Images/smallBackgroundImage.jpg", UriKind.Relative);

// An array of URIs will do the trick
CycleImages = new Uri[]
{ // You can have up to 9 images
new Uri("/Images/cycleImage1.jpg", UriKind.Relative),
new Uri("/Images/cycleImage2.jpg", UriKind.Relative),
new Uri("/Images/cycleImage3.jpg", UriKind.Relative),
new Uri("/Images/cycleImage4.jpg", UriKind.Relative),
new Uri("/Images/cycleImage5.jpg", UriKind.Relative),
new Uri("/Images/cycleImage6.jpg", UriKind.Relative),
new Uri("/Images/cycleImage7.jpg", UriKind.Relative),
new Uri("/Images/cycleImage8.jpg", UriKind.Relative),
new Uri("/Images/cycleImage9.jpg", UriKind.Relative),
}
};

Another way to setup the Cyclic Template is directly in your WMAppManifest file by assigning an image directly like this:

2012-12-13_1150

#3- Your app needs to support all three Windows Phone resolutions. This link will take you to the MSDN documentation on how to target different resolutions. Here is a screenshot of the new resolutions for Windows Phone from the docs and also my WMAppManifest file.

2012-12-13_1143

2012-12-13_0927

Great, now you’re armed with the information you need to resubmit your application. Update your app through DevCenter, once it’s live in the Store go back into DVLUP and resubmit the app to the challenge. If you have any questions, send me an email to ext-lance.mccarthy(at)nokia(dot)com.