public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Add a bar button item to exit the app manually. Don't do this in productive apps - Apple won't approve it!
            // We have it here to demonstrate that iOS will relaunch the app if a download has finished.
            this.NavigationItem.LeftBarButtonItem = new UIBarButtonItem("Quit", UIBarButtonItemStyle.Plain, delegate {
                // Store all download info to disk. If iOS terminates the app, this would be handled in WillTerminate().
                // However this won't be triggered if the app is killed manually by this call.
                AppDelegate.SerializeAvailableDownloads();

                // Exit application with code 3.
                MusicListController.Exit(3);
            });

            // Magic line: allows starting music playback when app is backgrounded or even terminated!
            UIApplication.SharedApplication.BeginReceivingRemoteControlEvents();

            // We must set up an AVAudioSession and tell iOS we want to playback audio. Only then can music playback be used in the background.
            var audioSession = AVAudioSession.SharedInstance();

            audioSession.SetCategory(AVAudioSessionCategory.Playback);
            audioSession.SetActive(true);

            // Add a bar button item to reset all downloads.
            var refreshBtn = new UIBarButtonItem(UIBarButtonSystemItem.Refresh);

            refreshBtn.Clicked += async(sender, e) => {
                // Stop audio.
                this.PlayAudio(null);

                var pendingTasks = await this.Session.GetTasks2Async();

                if (pendingTasks != null && pendingTasks.DownloadTasks != null)
                {
                    foreach (var task in pendingTasks.DownloadTasks)
                    {
                        task.Cancel();
                    }
                }

                AppDelegate.AvailableDownloads.ForEach(info => info.Reset(true));

                AppDelegate.ResetAvailableDownloads();
                ((DelegateTableViewSource <DownloadInfo>)(this.TableView.Source)).Items = AppDelegate.AvailableDownloads;

                this.TableView.ReloadData();

                AppDelegate.SerializeAvailableDownloads();
            };


            // Add a button to stops playback.
            this.stopBtn = new UIBarButtonItem(UIBarButtonSystemItem.Stop)
            {
                Enabled = false
            };
            this.stopBtn.Clicked += (sender, e) => this.StopAudio();

            this.NavigationItem.RightBarButtonItems = new UIBarButtonItem[] { refreshBtn, this.stopBtn };


            // Initialize our session config. We use a background session to enabled out of process uploads/downloads. Note that there are other configurations available:
            // - DefaultSessionConfiguration: behaves like NSUrlConnection. Used if *background* transfer is not required.
            // - EphemeralSessionConfiguration: use if you want to achieve something like private browsing where all sesion info (e.g. cookies) is kept in memory only.
            using (var sessionConfig = UIDevice.CurrentDevice.CheckSystemVersion(8, 0)
                                ? NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration(SessionId)
                                : NSUrlSessionConfiguration.BackgroundSessionConfiguration(SessionId))
            {
                // Allow downloads over cellular network too.
                sessionConfig.AllowsCellularAccess = true;

                // We want our app to be launched if required.
                //sessionConfig.SessionSendsLaunchEvents = true;

                // Give the OS a hint about what we are downloading. This helps iOS to prioritize. For example "Background" is used to download data that was not requested by the user and
                // should be ready if the app gets activated.
                sessionConfig.NetworkServiceType = NSUrlRequestNetworkServiceType.Default;

                // Configure how many downloads we allow at the same time. Set to 2 to see that further downloads start once the first two have been completed.
                sessionConfig.HttpMaximumConnectionsPerHost = 2;

                // Create a session delegate and the session itself
                // Initialize the session itself with the configuration and a session delegate.
                var sessionDelegate = new SessionDelegate(this);
                this.Session = NSUrlSession.FromConfiguration(sessionConfig, (INSUrlSessionDelegate)sessionDelegate, null);
            }

            this.TableView.Source = new DelegateTableViewSource <DownloadInfo>(this.TableView, "MUSIC_CELL")
            {
                Items       = AppDelegate.AvailableDownloads,
                GetCellFunc = (item, cell) =>
                {
                    var musicCell = (MusicCell)cell;
                    musicCell.InitFromDownloadInfo(item);
                    return(musicCell);
                },
                RowSelectedFunc = (downloadInfo, cell, indexPath) =>
                {
                    // If a row gets tapped, download or play.
                    if (downloadInfo.Status != DownloadInfo.STATUS.Completed & downloadInfo.Status != DownloadInfo.STATUS.Downloading)
                    {
                        // Queue download.
                        this.EnqueueDownloadAsync(downloadInfo);

                        // Update UI once more. Download initialization might have failed	.
                        ((MusicCell)cell).InitFromDownloadInfo(downloadInfo);

                        this.TableView.ReloadRows(new NSIndexPath[] { indexPath }, UITableViewRowAnimation.None);
                    }
                    else if (downloadInfo.Status == DownloadInfo.STATUS.Completed)
                    {
                        // Play MP3.
                        this.currentSongIndex = indexPath.Row;
                        this.PlayAudio(downloadInfo);
                    }
                }
            };

            this.TableView.EstimatedRowHeight = 100;
            this.TableView.RowHeight          = UITableView.AutomaticDimension;
        }
 public SessionDelegate(MusicListController controller) : base()
 {
     this.controller = controller;
 }