Cross-Platform SongLoader Integration
Cross-Platform SongLoader Integration
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();
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);
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.
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
}
Hide Code
public static async Task<IEnumerable<Song>> Load()
{
using (var reader = new StreamReader(await OpenData())) {
return JsonConvert.DeserializeObject<List<Song>>(
await reader.ReadToEndAsync());
}
}
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.