MusicMotion/SongViewController.swift
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
This class manages the presentation of the queued songs and updates when the users context changes. |
*/ |
import UIKit |
class SongViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, SongManagerDelegate { |
// MARK: Properties |
static let textCellIdentifier = "SongCell" |
@IBOutlet weak var songTableView: UITableView! |
@IBOutlet weak var albumView: UIImageView! |
let motionManager = MotionManager() |
let songManager = SongManager() |
var cachedSongQueue = [Song]() |
// MARK: View Controller |
override func viewDidLoad() { |
super.viewDidLoad() |
setNeedsStatusBarAppearanceUpdate() |
motionManager.delegate = songManager |
/* |
This is currently needed to allow the Motion Activity Access dialog |
to appear in front of the app, instead of behind it. |
*/ |
DispatchQueue.main.async { |
self.motionManager.startMonitoring() |
} |
songManager.delegate = self |
// Save the inital queue to present to the user. |
cachedSongQueue = songManager.songQueue |
updateAlbumViewWithSong(nil) |
selectFirstRow() |
} |
func updateAlbumViewWithSong(_ song: Song?) { |
// If no song is passed in, just use the first song in the queue. |
guard let song = song ?? cachedSongQueue.first else { return } |
albumView.image = song.albumImage |
} |
func selectFirstRow() { |
let rowToSelect = IndexPath(row: 0, section: 0) |
songTableView.selectRow(at: rowToSelect, animated: false, scrollPosition: .none) |
tableView(songTableView, didSelectRowAt: rowToSelect) |
} |
// MARK: UITableViewDataSource |
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { |
return cachedSongQueue.count |
} |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { |
let cell = tableView.dequeueReusableCell(withIdentifier: SongViewController.textCellIdentifier, for: indexPath) |
let song = cachedSongQueue[indexPath.row] |
cell.textLabel!.text = song.artist |
cell.detailTextLabel!.text = song.title |
return cell |
} |
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { |
// Create the header based on the intensity. For example "Low Intensity Music". |
return songManager.contextDescription |
} |
// MARK: UITableViewDelegate |
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { |
let song = cachedSongQueue[indexPath.row] |
updateAlbumViewWithSong(song) |
} |
// MARK: SongManagerDelegate |
func didUpdateSongQueue(_ manager: SongManager) { |
let indexSet = IndexSet(integer: 0) |
// Cache the songs to avoid modifications to the data outside the view controller. |
cachedSongQueue = manager.songQueue |
DispatchQueue.main.async { |
self.songTableView.reloadSections(indexSet, with: .fade) |
self.updateAlbumViewWithSong(nil) |
self.selectFirstRow() |
} |
} |
func didEncounterAuthorizationError(_ manager: SongManager) { |
let title = NSLocalizedString("Motion Activity Not Authorized", comment: "") |
let message = NSLocalizedString("To enable Motion features, please allow access to Motion & Fitness in Settings under Privacy.", comment: "") |
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) |
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) |
alert.addAction(cancelAction) |
let openSettingsAction = UIAlertAction(title: "Open Settings", style: .default) { _ in |
// Open the Settings app. |
let url = URL(string: UIApplicationOpenSettingsURLString)! |
UIApplication.shared.openURL(url) |
} |
alert.addAction(openSettingsAction) |
DispatchQueue.main.async { |
self.present(alert, animated: true, completion:nil) |
} |
} |
} |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-09-28