Use o código e tenha 10% de desconto!

Swift Programe para iPhone e iPad

Guilherme Silveira, Joviane Jardim
Capa

Swift: Programe para iPhone e iPad

Sumário

  • 1 - Introdução
    • 1.1 - Motivação: mobile
    • 1.2 - Motivação: boas práticas e code smells
    • 1.3 - Agradecimentos
  • 2 - Projeto: nossa primeira App
    • 2.1 - Instalando o Xcode
    • 2.2 - Nossa primeira App
    • 2.3 - ViewController de cadastro de refeição
    • 2.4 - Boa prática: placeholder e keyboard type
    • 2.5 - Conectando a interface ao código
    • 2.6 - Conectando variáveis membro à sua parte visual: @IBOutlet
    • 2.7 - Resumo
  • 3 - Swift: a linguagem
    • 3.1 - Brincando no playground
    • 3.2 - Arrays
    • 3.3 - Boa prática: cuidado com inferência de tipos
    • 3.4 - Resumo
  • 4 - Swift: mapeando nossos modelos e introdução à Orientação a Objetos
    • 4.1 - Boa prática: organizando os dados
    • 4.2 - Boa prática: Good citizen (evite nulos) e o init
    • 4.3 - Nosso Good Citizen
    • 4.4 - Code smell (mal cheiro de código): opcional!
    • 4.5 - Resumo
  • 5 - Projeto: organizando modelos com OO e arquivos em grupos
    • 5.1 - Boa prática: crie um diretório por grupo
    • 5.2 - Movendo arquivos no sistema operacional
    • 5.3 - Aplicando o básico de Orientação a Objetos
    • 5.4 - Resumo
  • 6 - Listando as refeições com TableViewController
    • 6.1 - Tabelas dinâmicas usando Dynamic Prototypes
    • 6.2 - Resumo
  • 7 - Projeto: lista de refeições
    • 7.1 - Resumo
  • 8 - Navegando entre telas
    • 8.1 - Navegando com uma pilha de telas
    • 8.2 - Resumo
  • 9 - Design pattern: delegate
    • 9.1 - Configurando um delegate via segue
    • 9.2 - Code smell: nomes genéricos demais e como extrair um protocolo
    • 9.3 - Resumo
  • 10 - Relacionamento um para muitos: lista de alimentos
    • 10.1 - Protocolos da API
    • 10.2 - Seleção múltipla e Cell Accessory
    • 10.3 - Desselecionando elementos
    • 10.4 - Armazenando a seleção
    • 10.5 - Resumo
  • 11 - Criando novos itens
    • 11.1 - Pushando views para a pilha programaticamente
    • 11.2 - Voltando de um push programático
    • 11.3 - Invocando um delegate de forma programática
    • 11.4 - Resumo
  • 12 - Mostrando os detalhes de uma refeição com Long press
    • 12.1 - Recuperando onde ocorreu um evento de long press
    • 12.2 - Mostrando os detalhes em um alerta
    • 12.3 - Mostrando os detalhes dos itens
    • 12.4 - Resumo
  • 13 - Alerta: optionals e erros
    • 13.1 - Boa prática: evite optional, garanta tudo com if let
    • 13.2 - Tratando o erro com uma mensagem novamente
    • 13.3 - Boa prática: mensagens de erro descritivas
    • 13.4 - Refatoração: tratando diversos erros
    • 13.5 - Parâmetros default
    • 13.6 - Boa prática: Single Responsibility Principle, Princípio de Responsabilidade Única
    • 13.7 - Casos mais complexos de tratamento de erro
    • 13.8 - Code smell: Nested ifs
    • 13.9 - Resumo
  • 14 - Removendo uma refeição
    • 14.1 - Ações destrutivas e estilos
    • 14.2 - Passando uma função como callback
    • 14.3 - Indentificando a linha a ser removida
    • 14.4 - Removendo e atualizando a tela
    • 14.5 - Closures
    • 14.6 - Code smell: closures a rodo
    • 14.7 - Resumo
  • 15 - Armazenando as refeições dentro do file system
    • 15.1 - Salvando as refeições no sistema de arquivos
    • 15.2 - Salvando e lendo itens no sistema de arquivos
  • 16 - Boa prática: dividindo responsabilidades e o Data Access Object
    • 17 - Aonde chegamos e próximos passos
      Capítulo1

      Introdução

      1.1 - Motivação: mobile

      O mercado iOS cresce cada vez mais no Brasil, e se a decisão de uma empresa ou indivíduo é a de criar aplicações nativas, a escolha prática para o mundo iOS acaba sendo entre Objective C ou Swift.

      Como uma linguagem nova e beta, Swift ainda possui espaço para pequenas mudanças que podem alterar a maneira de um programador desenvolver uma aplicação, mas nesse instante a Apple já a considera madura o suficiente para que novos aplicativos possam ser criados com ela.

      Por ser nova, foram trazidos conceitos que estão em voga na comunidade de desenvolvimento em geral, como podemos ver a influência da linguagem Scala em Swift.

      Como uma linguagem compilada e com uma IDE rica, recebemos muitas notificações de possíveis erros ainda em tempo de desenvolvimento, o que evita diversos erros tradicionais, como o acesso a ponteiros inválidos na memória, algo muito fácil de se proteger em Swift.

      Para desenvolvedores novos no mundo iOS, este livro busca ser um guia que ensina diversas partes da linguagem e da API disponível durante a criação e manutenção de uma aplicação mobile completa.

      Todos os níveis de desenvolvedores podem se beneficiar dos conceitos de boas práticas, code smells, refatorações e design patterns apresentados no livro.

      1.2 - Motivação: boas práticas e code smells

      O objetivo desse livro não é somente guiá-lo através de sua primeira aplicação iOS, mas sim de ser capaz de julgar por si só o que é uma boa estratégia de programação, por meio da introdução de uma dezena de boas práticas e code smells que facilitam ou dificultam a manutenção do código com o passar do tempo.

      Um code smell é um sinal forte de que existe algo de estranho no código, não uma garantia de que exista um problema. Da mesma forma, boas práticas e design patterns possuem situações específicas que podem trazer mais mal do que benefícios. Como fazemos no livro, toda situação encontrada deve ser analisada friamente: qual o custo de manter o código como está e qual o custo de refatorá-lo?

      Saber pesar e tomar decisões como essa diferenciam um programador iniciante de um profissional e é isso que buscamos aqui: não somente ensinar a programar, mas sim criar profissionais em nossa área.

      São dezenas de boas práticas, design patterns e code smells catalogados no decorrer do livro que podem ser acessados diretamente através do índice remissivo.

      1.3 - Agradecimentos

      Gostaria de agradecer ao desafio proposto pelo Paulo Silveira e o Adriano Almeida. Não é fácil escrever um livro de boas práticas de linguagem e API quando uma é tão nova e a outra carregada de decisões antigas. É delicado entender as implicações de cada decisão da linguagem, mas o aprendizado que passamos por este projeto é o que trouxe a ele tanto valor.

      Um agradecimento especial ao Hugo Corbucci que tanto nos ajudou na revisão do livro, e ao Rodrigo Turini, ambos compartilharam conosco os bugs, as dificuldades e as alegrias de utilizar e ensinar uma linguagem ainda em desenvolvimento. Agradecemos também pelas conversas e discussões de padrões e boas práticas com o Maurício Aniche, além do Francisco Sokol, Diego Chohfi, Ubiratan Soares e outros.

      Capítulo2

      Projeto: nossa primeira App

      2.1 - Instalando o Xcode

      O processo de instalação do Xcode se tornou bem simples, basta acessar a Apple Store e procurar pelo Xcode. Clique em instalar.

      download-xcode.png
      Fig. 2.1


      Se você deseja usar uma versão beta do Xcode, entre no programa de beta developers da Apple e siga o link de download de uma versão beta. Cuidado, versões beta podem sofrer alterações e quebrar a qualquer instante - e quebram.

      2.2 - Nossa primeira App

      Nossa aplicação será um gerenciador de calorias e felicidade. Como usuário final eu faço um diário das comidas que ingeri, indicando quais alimentos estavam dentro dela e o quão feliz fiquei. Meu objetivo final seria descobrir quais alimentos me deixam mais felizes com o mínimo de calorias possíveis, um paraíso.

      Para isso será necessário cadastrar refeições (Meal) e para cada refeição queremos incluir os itens (Item) que a compõem. Desejamos listar essas refeições e fazer o relacionamento entre esses dois modelos, afinal uma refeição possui diversos itens, além de armazenar todos esses dados no celular.

      Por fim, veremos o processo de execução de nossa app em um simulador, e o de deploy de nossa app tanto em um celular particular para testes quanto na app store.

      Isso tudo será intercalado com seções de boas práticas de desenvolvimento de softwares e caixas de informações extras, ambos ganchos para que você possa se tornar um bom programador à medida que pesquisa a informação contida nessas seções e se aprofunda nelas. Não se sinta obrigado a pesquisá-las no mesmo momento que as lê, sugiro, inclusive, que você termine primeiro o conteúdo aqui apresentado para só então se aprofundar. Dessa forma, terá uma opinião mais formada sobre diversos itens ao entrar nessas discussões avançadas sobre qualidade de código, usabilidade etc.

      Ao término de nossa jornada, teremos uma aplicação com diversas funcionalidades, entre elas, adicionar novas refeições:

      sundubu.png
      Fig. 2.2


      Visualizar seus detalhes e removê-las desejado:

      remove.png
      Fig. 2.3


      Pronto para começar?

      2.3 - ViewController de cadastro de refeição

      Vamos criar uma nova aplicação. No Xcode, escolhemos "Criar um novo projeto" e, no Wizard que segue, escolhemos iOS, SingleViewApplication, que seria uma aplicação de uma tela só. Aos poucos, evoluiremos a mesma para mais telas. O nome do nosso projeto é eggplant-brownie e a organização br.com.alura.

      Escolhemos a linguagem swift e nosso alvo será o iPhone. A tela de criação fica então como a seguir:

      novo-projeto.png
      Fig. 2.4


      Logo de cara abriremos a nossa janela de criação de interface principal: o storyboard (chamado Main.storyboard dentro da pasta eggplant-brownie). Ao clicarmos nele, somos capazes de ver uma janela quadrada que será a primeira tela de nossa aplicação: nosso ViewController. O View Controller é chamado assim tanto por ser responsável pela View quanto por fazer o controle do que será executado ao interagirmos com essa View.

      Tem algo de estranho aqui, nossa tela está quase quadrada e sabemos que um iPhone não é quadrado. Vamos escolher o view controller clicando no quadrado e, em seguida, no botão amarelo que aparece no topo à esquerda do quadrado:

      storyboard.png
      Fig. 2.5


      No lado direito, podemos navegar entre diversas propriedades do atual elemento escolhido. Na aba Attributes, temos uma seção chamada Simulated Metrics onde alteramos a opção size, escolhendo iPhone 4-inch. Agora sim temos um tamanho compatível com um iPhone de 4 polegadas.

      adequando-tela.png
      Fig. 2.6


      Desejamos adicionar duas mensagens de texto e dois campos de texto, um para o nome da comida (name) e outro para o nível de felicidade com ela (happiness). Primeiro, buscamos na barra de componentes (canto inferior direito) um campo chamado Label:

      componentes.png
      Fig. 2.7


      E agora o arrastamos duas vezes para nosso ViewController. O resultado são dois labels com nomes sem sentido:

      labels.png
      Fig. 2.8


      Precisamos trocar seus valores. Afinal, um representará o nome e o outro nosso nível de felicidade com aquela comida. Um duplo clique no label permite alterar seu valor. Mudemos para Name e Happiness:

      labels-final.png
      Fig. 2.9


      Adicionamos agora dois campos de Text Field da mesma forma, um para Name e um para Happiness. No mesmo canto inferior direito, procuramos por Text Field e arrastamos o resultado duas vezes.

      Colocamos um botão, procurando pelo componente chamado Button e, assim como com outros componentes, mudamos seu texto para add.

      O resultado de nosso storyboard é esse:

      storyboard1.png
      Fig. 2.10


      O próximo passo é rodar nosso programa em um iPhone. Mas calma lá, eu não tenho um iPhone 4, 5, 6 etc., a todo instante. Quero primeiro ver como ficaria em um iPhone no meu computador, então vamos simular um iPhone. Para isso clicamos no botão Play que fica no canto superior esquerdo da janela.

      play.png
      Fig. 2.11


      Poderíamos rodar em outro iPhone, repare que podemos trocar o modelo a qualquer instante que desejarmos. Por exemplo, ao escolher um iPhone 5:

      toolbar-play-modelo-iphone.png
      Fig. 2.12


      O resultado é a tela de nosso programa rodando:

      simulador.png
      Fig. 2.13


      Podemos diminuir o zoom do emulador escolhendo, na aplicação iOS Simulator, menu Window, submenu Scale e a opção que acharmos mais adequada. Podemos também optar por mostrar o teclado em nosso emulador no menu Hardware, submenu Keyboard e Toggle software keyboard.

      Emulador ou simulador?

      Um emulador emula também o hardware, o simulador utiliza o hardware da máquina onde está rodando (host). No nosso caso, estamos usando um simulador, com o hardware de nossa máquina, portanto nossa aplicação rodará em geral mais rápido do que em um iPhone de verdade. Lembre-se sempre disso antes de colocar uma aplicação que abusa de processamento disponível para o mundo: você quer rodá-la em um emulador ou em seu celular antes para conferir seu desempenho.

      Ainda tem algo de estranho em nossa aplicação, o campo de felicidade permite digitar texto. Não desejamos isso. Podemos parar o emulador clicando no botão de stop no canto superior esquerdo.

      stop.png
      Fig. 2.14


      Ao selecionarmos um campo de texto como o de felicidade, notamos que à direita, na aba de propriedades, ao final das informações para Text Field, temos uma opção que indica o tipo de teclado, o Keyboard Type:

      textfield-properties.png
      Fig. 2.15


      Vamos escolher o tipo chamado Number Pad. Escolhemos também um texto padrão para ficar no fundo dos dois campos de texto, um placeholder, que será dani's cheesecake, guilherme's sundubu etc e 1 for sad, 5 for amazing.

      textfield-placeholder-e-type.png
      Fig. 2.16


      Rodamos nosso programa clicando novamente no Play e, agora, ao clicarmos no campo de texto do número, podemos verificar que o teclado que aparece é o teclado numérico, facilitando bastante a entrada de informações pelo usuário final.

      2.4 - Boa prática: placeholder e keyboard type

      Formulários cuja entrada de dados não seja do dia a dia do usuário final podem deixá-lo perdido. Um formulário de login é tão comum que não precisa de placeholder e a tela fica mais limpa. Já um placeholder em um formulário complexo que o usuário vê pela primeira vez pode ajudá-lo a entender que tipo de valor o programa espera dele.

      Além do placeholder, o tipo de teclado ajuda o usuário ao digitar dados específicos como e-mails, números inteiros ou decimais.

      Sempre que adicionar um campo de texto em sua aplicação, lembre-se de configurar o placeholder e o keyboard type adequado.

      Dica: cutuque as propriedades

      Brinque com algumas propriedades de fonte de seu componente Label. Mas lembre-se: é raro que uma aplicação com muitos estilos de fonte seja lembrada por esse fator. Evite muitas variações de fonte em sua aplicação. Não crie 100 estilos diferentes para 3 telas.

      Dica: salvando seus arquivos

      Note que toda vez que rodamos nosso programe ele é salvo automaticamente. Para perceber se seu arquivo não está salvo, você verifica que o nome dele está em negrito ou seu ícone está escurecido:

      salvando.png
      Fig. 2.1


      2.5 - Conectando a interface ao código

      Mas o que acontece quando clicamos no botão add? Desejamos executar algum código ao clicar neste botão. Para isso, abrimos o arquivo ViewController.swift, onde definiremos uma função em Swift. Clicamos no nome do arquivo na barra esquerda:

      view-controller.png
      Fig. 2.17


      Quem é ele? Prazer, nosso ViewController, que já vem um comportamento mínimo:

      import UIKit
      
      class ViewController: UIViewController {
          override func viewDidLoad() {
              super.viewDidLoad()
              // Do any additional setup after loading the view,
              // typically from a nib.
          }
      
          override func didReceiveMemoryWarning() {
              super.didReceiveMemoryWarning()
              // Dispose of any resources that can be recreated.
          }
      }
      

      Os dois métodos que a IDE adicionou são opcionais, portanto os removemos para ficarmos com nosso ViewController puro:

      import UIKit
      
      class ViewController: UIViewController {
      
      }
      

      O básico da linguagem aqui é que um ViewController herda de UIViewController. Só isso! O que queremos é adicionar uma função que será invocada quando o botão add seja clicado. Nada mais natural que definirmos nossa função como add. Toda vez que o botão for clicado, a função poderá ser chamada.

      import UIKit
      
      class ViewController: UIViewController {
          func add() {
      
          }
      }
      

      Queremos que essa função seja invocada toda vez que acontecer algo com nossa interface com o usuário. Isto é, gostaríamos que essa função fosse um listener dos eventos da nossa view. Portanto, nós o anotamos de modo a dizer ao Interface Builder (IB) que este método de nossa classe de ViewController é uma ação (Action) que será informada pela tela. O método é anotado como @IBAction:

      @IBAction func add() {
      
      }
      

      Para testar nosso callback, adicionamos uma impressão ao log:

      @IBAction func add() {
          println("button pressed!")
      }
      

      O log ficará na parte de baixo da tela, e aparecerá automaticamente ao imprimirmos algo, ou podemos mostrá-lo acessando o menu View, submenu Debug Area, opção Hide/Show Debug Area.

      icones.png
      Fig. 2.18


      Esses 3 botões (os de baixo para Yosemite e mais recente, os de cima para mais antigos) que se encontram no canto superior direito da janela do Xcode servem para esconder diferentes barras da aplicação: a barra de navegação nos arquivos do projeto (Navigator, Command+1 para mostrar, Command+0 para esconder), a barra de propriedades (Utilities) e a barra que mostra o console e o debug embaixo (Debug). Utilize a cada instante o modo que for mais agradável para a tarefa que está efetuando.

      Rodamos o programa, como sempre, clicando em Play, e, na aplicação, clicamos no botão add, mas nosso log na IDE não mostra nada:

      empty-log.png
      Fig. 2.19


      Claro, nós ainda não conectamos o botão add com nossa função. Podemos fazer isso de diversas maneiras e a primeira que veremos aqui é feita arrastando o código para o botão visualmente. Mas como arrastar algo visual para o código se a IDE mostra somente uma coisa por vez?

      No topo, à direita do Xcode, ao lado dos ícones para exibir/esconder as barras, conseguimos modificar a maneira de visualizar nossa área de trabalho. O primeiro botão ativa a visualização tradicional que utilizamos até agora. O segundo ativa a visualização que permite abrir dois editores ao mesmo tempo e é nela que costumamos trabalhar enquanto desenvolvemos a parte visual de nossas apps. Vamos clicar nesse botão.

      top-right.png
      Fig. 2.20


      Abrimos o storyboard clicando na barra à esquerda e clicamos no nosso ViewController dentro dele. Automaticamente o assistente (a parte da direita) abre o código-fonte do controller:

      storyboard-with-viewcontroller.png
      Fig. 2.21


      Note a bola vazia ao lado de nosso @IBAction. É ela que arrastamos para conectar ao botão add:

      conectando.png
      Fig. 2.22


      Testamos nossa aplicação e, ao clicarmos no botão, o log indica que o evento ocorreu. Sucesso:

      log-sucesso.png
      Fig. 2.23


      De volta ao Xcode, ao selecionarmos o botão add, podemos verificar na última aba de propriedades (Connections Inspector - último ícone à direita) que a ação Touch Up Inside invocará nossa função.

      connections-inspector.png
      Fig. 2.24


      Poderíamos acessar esta listagem de eventos (Sent Events) e puxar qualquer um dos eventos para uma função de callback que definimos. No entanto, não necessitamos de mais nenhuma agora.

      N maneiras: o mesmo resultado

      Essas são só duas das maneiras de trabalhar com o Xcode para criar uma @IBAction, e existem outras que veremos. Mesmo que no final todas tenham o mesmo resultado, tentaremos mostrar diversas delas para que você possa escolher aquela em que sentir mais prática de acordo com o que você tem em mãos aberto em sua tela naquele instante - ou de quais configurações deseja fazer ao criar uma IBAction ou similares.

      Chegou a hora de ler os dados dos dois campos, Name e Happiness. Dentro de nossa função, vamos imprimir os dois, primeiro declarando duas Strings e concatenando-as durante a impressão:

      @IBAction func add() {
          var name : String = "guilherme's sundubu";
          var happiness : String = "5";
          println("eaten: \(name) \(happiness)!");
      }
      

      Note que em Swift o ; é opcional, ele só é obrigatório quando desejar utilizar duas expressões na mesma linha, portanto podemos remover os ;:

      @IBAction func add() {
          var name : String = "guilherme's sundubu"
          var happiness : String = "5"
          println("eaten: \(name) \(happiness)!")
      }
      

      Como já estamos inicializando as variáveis no mesmo instante de suas declarações, não precisamos declarar seus tipos, elas têm seus tipos inferidos direto na inicialização:

      @IBAction func add() {
          var name = "guilherme's sundubu"
          var happiness = "5"
          println("eaten: \(name) \(happiness)!")
      }
      

      Além disso, tanto o nome quanto a felicidade não mudam de valor, de modo que podemos declará-las como referências imutáveis, ou seja, constantes. Podemos fazer isso utilizando a palavra reservada let:

      @IBAction func add() {
          let name = "guilherme's sundubu"
          let happiness = "5"
          println("eaten: \(name) \(happiness)!")
      }
      

      2.6 - Conectando variáveis membro à sua parte visual: @IBOutlet

      Voltando ao código, não queremos valores arbitrários como "guilherme's sundubu" ou "5". Desejamos ler o valor de nossos campos de texto. Como fazer isso? Da mesma maneira como conectamos uma função a um elemento visual, podemos conectar um elemento visual por inteiro a uma variável. No nosso caso, queremos representar um UITextField, portanto nossa variável será deste tipo:

      var nameField: UITextField
      var happinessField: UITextField
      

      Cuidado, pois não declaramos essas variáveis como locais à função! Assim como a função, elas são membros de nossa classe, membros de nosso ViewController:

      import UIKit
      
      class ViewController: UIViewController {
      
          var nameField: UITextField
          var happinessField: UITextField
      
          @IBAction func add() {
              let name = "guilherme's sundubu"
              let happiness = "5"
              println("eaten: \(name) \(happiness)!")
          }
      
      }
      

      Mas, na hora em que a adicionamos, a IDE indica erros. Ao clicarmos no ícone vermelho que representa um erro na barra à esquerda, vemos a mensagem de que a Class ViewController has no initializers:

      no-initializers.png
      Fig. 2.25


      Isso ocorre pois toda variável membro deve ser inicializada ou declarada como opcional.

      Erros de compilação

      Infelizmente o parser e compilador da linguagem Swift pode ser perder em seu código com uma certa facilidade. Caso o Xcode não mostre o erro mencionado, tente rodar sua aplicação, nesse instante é certo que ele tentará compilar seu código e encontrará o erro. Sempre que era para ter um erro de compilação e o Xcode não mostrar para você, tente rodar sua aplicação, forçando a compilação.

      Colocamos o ! ao final da declaração para indicar que ela é opcional para a criação de um ViewController.

      var nameField: UITextField!
      var happinessField: UITextField!
      

      Cuidado: opcionais com !

      Cuidado: uma variável declarada opcional com ! que tenha valor nulo e seja acessada pode crashear sua aplicação. Veremos outra maneira de declarar e acessar variáveis opcionais, além de vantagens e desvantagens de cada abordagem no decorrer do conteúdo aqui apresentado.

      Não desejamos programar de qualquer jeito e uma das principais boas práticas que veremos diversas vezes estará ligada ao uso adequado de valores opcionais para evitar erros em nossa aplicação. Não pretendemos ensinar de qualquer maneira a utilização de ! nem mesmo incentivar o uso indiscriminado do mesmo: seremos bem críticos em relação a ele. Por enquanto, adotamos o ! na declaração de nossas variáveis para indicar ao compilador que a variável é opcional mas nós, desenvolvedores, sabemos que ela tem valor (e corremos o risco).

      Da mesma maneira como fizemos com nossa ação, devemos anotar nossas variáveis. Desta vez, nós as anotamos como @IBOutlets e puxamos a bola vazia ao lado da variável name para nosso campo name na interface visual:

      outlets.png
      Fig. 2.26


      Agora, dentro de nossa função de adicionar uma nova refeição, podemos pegar o valor de nossos campos. Em cada um deles, utilizamos a propriedade text para extrair seus valores:

      import UIKit
      
      class ViewController: UIViewController {
      
          @IBOutlet var nameField: UITextField!
          @IBOutlet var happinessField: UITextField!
      
          @IBAction func add() {
              let name = nameField.text
              let happiness = happinessField.text
              println("eaten: \(name) \(happiness)!")
          }
      
      }
      

      Ao clicarmos no botão, vemos o resultado no log com os valores que entramos nos campos. É o que esperávamos!

      entrada-campos.png
      Fig. 2.27


      Ações conectadas

      Preste sempre atenção ao desenho dos círculos (as bolinhas) ao lado de suas ações. Se um círculo estiver preenchido, ele está conectado a algo. Se ele estiver vazio, então está desconectado. Se você renomear o método, ele se desconectará pois a conexão é feita via o nome do método. Tome cuidado sempre que renomear métodos ou atributos anotados. Tenha cuidado também em copiar/colar componentes conectados pois a conexão também é copiada. Caso seja necessário renomear ou copiar/colar um item já conectado, lembre-se de desfazer a conexão efetuada anteriormente, pois o Xcode acusará um erro:

      problema-connection.png
      Fig. 2.1


      Se você rodar a aplicação com uma conexão mal feita, ela pode desde (sem querer) funcionar de maneira inesperada como parar.

      Nome dos campos

      Existe um padrão comum em desenvolvimento de interfaces de programas desktop baseado na notação húngara, onde tentamos indicar no nome da variável qual o seu tipo.

      Um combo box para representar o gênero de um usuário poderia se chamar cbGender, enquanto o campo de texto com seu nome seria o txtName. Esse padrão não é seguido como regra geral no desenvolvimento de aplicações iOS. Outro padrão comum é utilizar field como prefixo ou sufixo. Aqui adotamos field como sufixo, assim como é feito no nome das classes (Controller, Delegate etc) nas APIs do iOS.

      2.7 - Resumo

      Somos capazes de criar uma interface mínima com nosso usuário, além de receber valores e ter métodos invocados quando determinados eventos ocorrem.

      Aprendemos um pouco da linguagem Swift: sabemos criar uma classe, variáveis locais e membros, além da definição de constantes. Vimos também que a linguagem é type safe inclusive em relação à não inicialização de variáveis: fomos obrigados a utilizar o ! para dizer que sabemos que essa variável é opcional e terá um valor válido em execução.

      Aprendemos também a usar nossa IDE para navegar no projeto e construir nossa interface, que foi rodada em um simulador do iPhone. Somos capazes de testá-la em diversas versões de iPhones.

      Durante esse caminho todo conseguimos perceber algumas boas práticas de desenvolvimento de software em geral, tanto em relação à utilização de constantes quando cabível quanto em relação à interface que oferecemos para nosso usuário final.

      Nosso próximo passo é aprender mais dessa linguagem para podermos modelar nossas classes que representarão uma refeição (Meal) e um item contido nela (Item).

      Dados do produto

      Número de páginas:
      245
      ISBN:
      978-85-5519-052-0
      Data publicação:
      12/2014

      Compartilhe!

      Compartilhe no Facebook Compartilhe no Twitter