Prática 2: Integrando o Core Data
Assista e acompanhe a prática em sala dos exercícios "Integrando o Core Data". Execute as instruções conforme a apresentação.
Exercício 1: Apresentando a Lista de Atividades
1.1. Remover as propriedades dos Text Fields
No arquivo ViewController.swift remover as propriedades repetitionsLimitTextField e timeLimitTextField.
1.2. Remover o código de inicialização do Text Fields
No arquivo ViewController.swift no método viewDidLoad localizar e remover os trechos de código abaixo:
// Cria o botão de reinicio da sessão let resetButton = UIButton.buttonWithType(UIButtonType.System) as UIButton resetButton.setTitle("Reiniciar", forState: UIControlState.Normal) resetButton.sizeToFit() resetButton.frame = CGRect(x: (self.view.frame.size.width / 2 - resetButton.frame.size.width / 2), y: 28, width: resetButton.frame.size.width, height: resetButton.frame.size.height) resetButton.addTarget(self, action: "handleResetButton:", forControlEvents: UIControlEvents.TouchUpInside) self.view.addSubview(resetButton)
// Cria o UITextField para configurar o limite de repetições self.view.addSubview(self.repetitionsLimitTextField) self.view.addSubview(self.timeLimitTextField)
1.3. Atualizar o código das propriedades maxRepetitions e duration
No arquivo ViewController.swift atualize as propriedades de acordo com o código abaixo:
var maxRepetitions: Int {if let r = self.repetitionsLimitTextField.text.toInt() { return r }return 0 }
var duration: NSTimeInterval {if let tl = self.timeLimitTextField.text.toInt() { return NSTimeInterval(tl) }return NSTimeInterval(0) }
1.4. Incluir as propriedades do Data Context
No arquivo ViewController.swift incluir as propriedades conforme o código abaixo:
lazy var activities: [Activity] = {
let acts = TraqtDataContext.sharedInstance.activities.getAll()
return acts
}()
var currentActivity: Activity! {
didSet {
self.configSession()
}
}
1.5. Incluir o UIPickverView de seleção de atividades
No arquivo ViewController.swift incluir o código para declaração do UIPickverView no método viewDidLoad:
// Cria o picker view de listagem e seleção de atividades
let pickerFrame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 100)
let activityPicker = UIPickerView(frame: pickerFrame)
activityPicker.delegate = self
activityPicker.dataSource = self
activityPicker.showsSelectionIndicator = true
self.view.addSubview(activityPicker)
1.6. Declarar a classe ViewController como aderente aos protocolos do UIPickerView
No arquivo ViewController.swift atualizar a declaração da classe para incluir os protocolos conforme o código abaixo:
class ViewController: UIViewController, SessionParameters<b>, UIPickerViewDelegate, UIPickerViewDataSource</b> {
1.7. Inserir o código dos métodos necessários dos protocolos
No arquivo ViewContoller.swift incluir os métodos dos protocolos conforme o código abaixo:
//
// MARK: - UIPickerViewDataSource
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.activities.count
}
//
// MARK: - UIPickerViewDelegate
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// Alterna a seleção da atividade atual e reinicia a sessão
self.sessionTrack.cancelSession()
self.currentActivity = self.activities[row]
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.activities[row].name
}
1.8. Executar o App e verificar a carga do Picker View
1.9. Adicionar uma Extension para tornar a classe Acitvity aderente ao protocolo SessionParameters
No grupo Model crie um novo arquivo do tipo Swift File com o nome Activity+SessionParameters.swift e adicione o seguinte código:
extension Activity : SessionParameters {
/// Quantidade de repetições máximas dessa sessão
var maxRepetitions: Int {
return repetitions!.integerValue
}
/// Duração da sessão
var duration: NSTimeInterval {
return NSTimeInterval(timeLimit?.floatValue ?? 0)
}
/// Habilitar vibrações quando uma repetição é adicionada?
var vibrate: Bool {
return enableVibration?.boolValue ?? false
}
}
1.10. Remova a implementação do protocolo SesionParameters da classe ViewController
No arquivo ViewController.swift localize e remova todas as referencias ao protocolo SessionParameters:
- Exclua as propriedades maxRepetitions, duration e vibrate
- Exclua a declaração de aderência ao protocolo na declaração da classe, conforme o código abaixo:
class ViewController: UIViewController,SessionParameters,UIPickerViewDelegate, UIPickerViewDataSource {
1.11. Atualize o método handleVibrationsButton:sender:
No arquivo ViewController.swift localize e atualize o método conforme o código abaixo:
func handleVibrationsButton(sender: UIButton) { self.sessionTrack.enableVibration = !self.sessionTrack.enableVibration let title = self.sessionTrack.enableVibration ? "Desabilitar Vibração" : "Habilitar Vibração" sender.setTitle(title, forState: UIControlState.Normal) }
1.12. Atualize a implementação do método configSession
No arquivo ViewControlle.swift localize e atualize o método conforme o código abaixo:
func configSession() {self.sessionTrack = SessionTrack(sessionParameters: self)self.sessionTrack = SessionTrack(sessionParameters: self.currentActivity) // Restante do código // ... }
1.13. Inclua a inicialização da propriedade currentActivity
No arquivo ViewController.swift localize o método viewDidLoad e inclua o código abaixo:
// Configura a sessão self.currentActivity = self.activities[0] self.configSession()
1.14. Inclua as propriedades para os Labels de exibição das configurações da atividade selecionada
No arquivo ViewController.swift inclua as propriedades conforme o código abaixo:
lazy var maxRepetitionsLabel: UILabel = { let label = UILabel(frame: CGRect(x: 20, y: 180, width: 100, height: 100)) label.text = "Repetições max.: 0" label.sizeToFit() return label }() lazy var durationLabel: UILabel = { let label = UILabel(frame: CGRect(x: 20, y: 200, width: 100, height: 100)) label.text = "Tempo limite: 0" label.sizeToFit() return label }()
1.15. Inclua os Labels na View Principal
No arquivo ViewController.swift inclua os labels criados no item anterior, no método viewDidLoad conforme o código abaixo:
// Adiciona os outros componentes self.view.addSubview(self.maxRepetitionsLabel) self.view.addSubview(self.durationLabel)
1.16. Atualize a propriedade currentActivity
No arquivo ViewController.swift atualize a propriedade conforme o código abaixo:
var currentActivity: Activity! { didSet { self.configSession() // Atualiza os dados da atividade self.maxRepetitionsLabel.text = "Repetições max.: \(self.currentActivity?.repetitions ?? 0)" self.maxRepetitionsLabel.sizeToFit() self.durationLabel.text = "Tempo limite: \(self.currentActivity.duration.getFormattedInterval(miliseconds: false))" self.durationLabel.sizeToFit() } }
Exercício 2: Salvando e Apresentando Sessões
2.1. Criar um arquivo para a enumeração SessionOutcome
No grupo Model inserir um novo arquivo do tipo Swift File com o nome SessionOutcome.swift e incluir o código abaixo:
/// Enumera os status com o qual uma sessão pode ser concluída
enum SessionOutcome : Int {
/// A sessão foi concluída normalmente
case Completed
/// A sessão foi cancelada
case Cancelled
}
2.2. Atualize o protocolo SessionParameters
Abra o arquivo SessionParameters.swift e atualize o protocolo inserindo o método conforme o código abaixo:
/// Salva uma sessão
func saveSession(outcome: SessionOutcome, startTime: NSDate, endTime: NSDate, elapsedTime: NSTimeInterval, totalRepetitions: Int)
2.3. Inclua a implementação do método na classe Activity
Abra o arquivo Activity+SessionParameters.swift e acrescente o código do novo método do protocolo conforme o código abaixo:
/**
Salva uma sessão na entidade de Sessões, associada a esta atividade.
- Parameters:
- outcome: Status com o qual a sessão foi concluída.
- startTime: Data/horário de início da sessão.
- endTime: Data/horário de conclusão da sessão.
- elapsedTime: Tempo transcorrido.
- totalRepetitions: Quantidade total de repetições.
*/
func saveSession(outcome: SessionOutcome, startTime: NSDate, endTime: NSDate, elapsedTime: NSTimeInterval, totalRepetitions: Int) {
TraqtDataContext.sharedInstance.sessions.add() {
$0.activitiy = self
$0.sessionOutcome = outcome.rawValue
$0.startTime = startTime
$0.endTime = endTime
$0.elapsedTime = elapsedTime
$0.totalRepetitions = totalRepetitions
}
}
2.4. Atualize o método completeSession
Abra o arquivo SessionTrack.swift e atualize o método conforme o código abaixo:
private func completeSession(isCancelled: Bool = false) { // Verifica se o estado da sessão não é cancelado ou completo if sessionState == .Running || sessionState == .Paused { self.chronometer.stop() self.sessionState = isCancelled ? .Cancelled : .Completed // Salva a sessão let outcome = isCancelled ? SessionOutcome.Cancelled : SessionOutcome.Completed self.sessionParameters.saveSession(outcome, startTime: self.startTime ?? NSDate(), endTime: NSDate(), elapsedTime: self.chronometer.elapsedTime, totalRepetitions: self.currentRepetitions) // Informa o usuário dessa instância qua a sessão foi concluída self.completionBlock?() } }
2.5. Adicione um TextView para histórico na view principal
No arquivo ViewController.swift adicione a propriedade conforme o código abaixo:
lazy var sessionsTextView: UITextView = {
let textView = UITextView(frame: CGRect(x: 0, y: self.view.center.y + 60, width: self.view.frame.width, height: 100))
return textView
}()
E adicione o componente a view principal no método viewDidLoad conforme o código abaixo:
self.view.addSubview(self.sessionsTextView)
2.6. Atualize a propriedade currentActivity
No arquivo ViewController.swift atualize a propriedade conforme o código abaixo:
var currentActivity: Activity! { didSet { self.configSession() // Atualiza os dados da atividade self.maxRepetitionsLabel.text = "Repetições max.: \(self.currentActivity.repetitions)" self.maxRepetitionsLabel.sizeToFit() self.durationLabel.text = "Tempo limite: \(self.currentActivity.duration.getFormattedInterval(miliseconds: false))" self.durationLabel.sizeToFit() // Mostra as sessões realizadas no TextView if let sessions = self.currentActivity.sessions where sessions.count > 0 { let dateFormatter = NSDateFormatter() dateFormatter.dateStyle = .ShortStyle dateFormatter.timeStyle = .ShortStyle var sessionHistory = "Sessões desta atividade:" for session in sessions { let s = session as! Session sessionHistory += "\n- Sessão em \(dateFormatter.stringFromDate(s.startTime!)), repetições: \(s.totalRepetitions ?? 0), tempo: \(NSTimeInterval(s.elapsedTime ?? 0).getFormattedInterval(miliseconds: false))" } self.sessionsTextView.text = sessionHistory } else { self.sessionsTextView.text = "Não há sessões registradas para essa atividade." } } }