0% found this document useful (0 votes)
81 views12 pages

Cross-Platform SongLoader Integration

The document describes steps to load song data from a JSON file into mobile applications for different platforms (iOS, Android, Windows Phone, UWP). It involves: 1. Adding code to each platform's project to load data using the SongLoader class and populate the UI. 2. Adding the songs.json file to each project. 3. Adding code to the SongLoader class to open the JSON file using platform-specific methods wrapped in compiler directives. 4. Running each application which should now display the song list from the loaded data.

Uploaded by

Abrahan Estrada
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
81 views12 pages

Cross-Platform SongLoader Integration

The document describes steps to load song data from a JSON file into mobile applications for different platforms (iOS, Android, Windows Phone, UWP). It involves: 1. Adding code to each platform's project to load data using the SongLoader class and populate the UI. 2. Adding the songs.json file to each project. 3. Adding code to the SongLoader class to open the JSON file using platform-specific methods wrapped in compiler directives. 4. Running each application which should now display the song list from the loaded data.

Uploaded by

Abrahan Estrada
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 12

Exercise 1

Use the Song Loader from the Shared


Project
Now, let's add some code into each project to use load data using
the SongLoader class. Follow the steps below for each platform you will be using:

iOS
1. Locate the ViewDidLoad method in the MyTunesViewController.cs.
2. Comment out the existing TableView.Source assignment.
3. Load the data using SongLoader.Load. This method uses the Task based Async pattern;
you will need to await the call and decorate ViewDidLoad with the async keyword.
4. Call ToList on the IEnumerable<Song> returned from SongLoader.Load. We'll use this
in the next step.
5. Create a new ViewControllerSource<Song> and assign the following properties:
o DataSource to the List from the previous step.
o TextProc to a lambda that returns the name of a song: s => s.Name.
o DetailTextProc to a lambda that returns the artist and album: s => s.Artist +
" - " + s.Album.
6. Assign the ViewControllerSource to TableView.Source.

Hide Code
public async override void ViewDidLoad()
{
base.ViewDidLoad();

//TableView.Source = new ViewControllerSource<string>(TableView) {


// DataSource = new string[] { "One", "Two", "Three" },
//};

// Load the data


var data = await SongLoader.Load();

// Register the TableView's data source


TableView.Source = new ViewControllerSource<Song>(TableView)
{
DataSource = data.ToList(),
TextProc = s => s.Name,
DetailTextProc = s => s.Artist + " - " + s.Album,
};
}

Android
1. Locate the OnCreate method in MainActivity.cs.
2. Comment out the existing ListAdapter assignment.
3. Load the data using SongLoader.Load. This method uses the Task based Async pattern;
you will need to await the call and decorate OnCreate with the async keyword.
4. Call ToList on the IEnumerable<Song> returned from SongLoader.Load. We'll use this
in the next step.
5. Create a new ListAdapter<Song> and assign the following properties:
o DataSource property to your new list.
o TextProc to a lambda that returns the song name: s => s.Name.
o DetailTextProc to a lambda that returns the artist and album: s => s.Artist +
" - " + s.Album.
6. Assign the object to the ListAdapter property.

Hide Code
protected async override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);

//ListAdapter = new ListAdapter<string>() {


// DataSource = new[] { "One", "Two", "Three" }
//};

var data = await SongLoader.Load();

ListAdapter = new ListAdapter<Song>()


{
DataSource = data.ToList(),
TextProc = s => s.Name,
DetailTextProc = s => s.Artist + " - " + s.Album
};
}

Windows Phone and UWP


1. Locate the OnNavigatedTo method in the MainPage.xaml.cs. For UWP you'll need to add
the method override manually.
2. Load the data using SongLoader.Load. This method uses the Task based Async pattern;
you will need to await the call and decorate OnCreate with the async keyword.
3. Take the resulting data and assign it to the DataContext property.
4. There is already a DataTemplate setup to display the song data.

Hide Code
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
DataContext = await SongLoader.Load();
}

Make sure each project compiles. It will fail at runtime because we haven't provided
the data yet - let's do that next.

Add the songs.json Data File


We will add the songs.json file from the downloaded materials into each platform-
specific project.
 iOS - Add the songs.json file into the Resources folder and make sure the build action is
marked asBundleResource.
 Android - Add the songs.json file into the Assets folder and make sure the build action is
marked asAndroidAsset.
 Windows Phone and UWP - Add the songs.json file into the root of the windows projects
and set the build action to Content.

Make sure all your projects still build successfully.

Add Code to Read the Data File


Now that we've got the data file added to each platform-specific project, we will
need to use platform-specific code to load our data. We can use any of the three
approaches outlined in the class session (conditional compilation, cloning and
partial classes), and you should experiment and try each one in turn; however for
the sake of time, we will use conditional compilation in these instructions.

All our work will be done in the SongLoader class in the shared project, specifically
we'll be working in the existing OpenData method which will open the file and
return it as a System.IO.Stream.
Follow the instructions below for the target platforms you want to support.

iOS
1. In the OpenData method, add a compiler directive for iOS; The Xamarin.iOS compiler
defines __IOS__for this purpose.
2. In your conditional code block, use the System.IO.File.OpenRead method to open the
file using theconst string FileName.
3. Make sure the iOS project builds.

Hide Code
private static Stream OpenData()
{
#if __IOS__
return File.OpenRead(Filename);
#else
// TODO: add code to open file here.
return null;
#endif
}
Android
1. Add a conditional marker for the Android code. Xamarin.Android defines
the __ANDROID__ symbol for this.
2. In your conditional code block, use
the Android.App.Application.Context.Assets.Open method to open the filename.
3. Make sure the Android project builds.

Hide Code
private static Stream OpenData()
{
#if __ANDROID__
return Android.App.Application.Context.Assets.Open(Filename);
#else
// TODO: add code to open file here.
return null;
#endif
}

Windows Phone and UWP


 Add conditional markers for Windows Phone and UWP. Microsoft
defines WINDOWS_PHONE_APP andWINDOWS_UWP for each platform respectively.
 In your conditional code blocks, use
theWindows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsyn
c method to open the filename. This returns a StorageFile.
 Call OpenStreamForRead on the StorageFile to retrieve a Stream.
 Because WinRT APIs are almost completely async, you will need to change the method
signature to beasync and use the await keyword - the call site will also need to be adjusted
for this.
 The code for the other platforms can remain the same - however you will get a compiler
warning because the method is decorated with async but doesn't contain any awaited calls
for iOS and Android.
 Make sure the Windows Phone project builds.

Hide Code
public static async Task<IEnumerable<Song>> Load()
{
using (var reader = new StreamReader(await OpenData())) {
return JsonConvert.DeserializeObject<List<Song>>(
await reader.ReadToEndAsync());
}
}

private async static Task<Stream> OpenData()


{
#if WINDOWS_PHONE_APP
var sf = await Windows.ApplicationModel.Package.Current.InstalledLocation.Get
FileAsync(Filename);
return await sf.OpenStreamForReadAsync();
#elif WINDOWS_UWP
var sf = await Windows.ApplicationModel.Package.Current.InstalledLocation.Get
FileAsync(Filename);
return await sf.OpenStreamForReadAsync();
#else
// TODO: add code to open file here.
return null;
#endif
}

Run the Application


Run the application on each platform - they should all display the song list.

In this exercise, we created a Shared Project and referenced it from iOS, Android
Windows Phone and Windows UWP projects. The shared project contained both
platform-agnostic code, as well as platform-specific code isolated using compiler
directives for each platform.

You might also like