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."
}
}
}