14 coisas que um desenvolvedor iOS deve saber

Com a permissão do autor, posto a tradução do artigo de Norberto Gil Vasconcelos "14 deve conhecer para um desenvolvedor iOS" ( link para o original ). No momento da publicação do artigo, a versão Swift 3. era relevante.

Como desenvolvedor iOS (atualmente absolutamente dependente do Swift), criei aplicativos a partir do zero, suportei aplicativos e trabalhei em várias equipes. Durante todo o tempo em que trabalho neste setor, sempre ouvi a frase: "Você não pode explicar, então não entende. Portanto, na tentativa de entender o que exatamente faço todos os dias, crio uma lista do que, na minha opinião, é importante para qualquer desenvolvedor de iOS. Vou tentar explicar cada momento o mais claramente possível. [Por favor, sinta-se à vontade para me corrigir, expressar sua opinião ou sugerir suas adições a esta lista.]


Tópicos: [ controle de versão | padrões arquitetônicos | Objetivo-C vs. Swift | reagir | gerenciador de dependências | armazenamento de informações | Vistas de coleção e exibições de mesa | UI | protocolos | curto-circuito | esquemas | testes | geolocalização | cadeias localizáveis ]


Aqui está minha lista, sem mais delongas, em ordem aleatória.

1 - Controle de versão


Parabéns, você é aceito! Extraia o código do repositório e comece a trabalhar. Parar o que?

O controle de versão é necessário para qualquer projeto, mesmo se você for apenas um desenvolvedor. Os sistemas mais usados ​​são Git e SVN.

O SVN é baseado em um sistema de controle de versão centralizado. Este é o repositório onde as cópias de trabalho são criadas e, para acessá-las, você precisa de uma conexão de rede. A autorização de alterações é realizada de maneira específica; o sistema monitora as alterações registrando cada arquivo, o histórico completo das alterações pode ser visualizado apenas no repositório. As cópias de trabalho contêm apenas a versão mais recente.

Gitusa um sistema de controle de versão distribuído. Você terá um repositório local onde poderá trabalhar, uma conexão de rede é necessária apenas para sincronização. Quando uma cópia de trabalho é alterada, o estado de todo o diretório é salvo, mas apenas as alterações feitas são registradas; O repositório e as cópias de trabalho têm um histórico completo de alterações.

2 - Padrões arquitetônicos


Seus dedos tremem de emoção, você descobriu o controle de versão! Ou é por causa do café? Deixa pra lá! Você está à beira, e chegou a hora da programação! Não. O que mais esperar?
Antes de sentar no teclado, você deve escolher o padrão arquitetural ao qual irá aderir. Se você não iniciou o projeto, deve corresponder ao padrão existente.
Existe uma grande variedade de padrões usados ​​no desenvolvimento de aplicativos móveis (MVC, MVP, MVVM, VIPER, etc.). Vou dar uma breve visão geral das ferramentas de desenvolvimento iOS mais usadas:

  • MVC — Model, View, Controller. Controller Model View, . View Controller , Controller . ? , View, (ViewController) . , MVC. MVC . ( !), , , Model, , . MVC , , iOS .


    MVC –
  • MVVMModel, View, ViewModel. ( ) View ViewModel, ViewModel , ViewModel, View - . ViewModel View, , .


    MVVM –


Para um entendimento mais profundo e informações sobre outros padrões, recomendo a leitura do artigo a seguir .

Isso pode não parecer muito, mas um código bem estruturado e organizado pode evitar muitas dores de cabeça. O grande erro que todo desenvolvedor comete em algum momento é simplesmente obter o resultado desejado e se recusar a organizar o código, acreditando equivocadamente que economiza tempo. Se você não concorda, ouça o velho Benji:
A cada minuto que você gasta organizando sua empresa, você economiza uma hora

- Benjamin Franklin

Nosso objetivo é obter um código intuitivo e fácil de ler, fácil de usar e manter.

3 - Objective-C vs Swift


Ao decidir em qual linguagem de programação escrever seu aplicativo, você deve saber quais recursos cada um deles possui. Se possível, prefiro usar o Swift. Por quê? Para ser sincero, o Objective-C tem muito poucas vantagens sobre o Swift. A maioria dos exemplos e tutoriais são escritos em Objective-C, e Swift faz ajustes nos paradigmas a cada atualização, o que pode ser desanimador. No entanto, esses problemas acabarão por desaparecer.

Comparado ao Objective-C, o Swift dá um salto de várias maneiras. É fácil de ler, parece inglês natural e, como não é construído em C, isso permite que você abandone as convenções tradicionais. Para quem conhece o Objective-C, isso significa que não há mais ponto e vírgula, e as chamadas de método e as condições de expressão não precisarão ser colocadas entre colchetes. Também é mais fácil manter seu código: o Swift precisa apenas de um arquivo .swift em vez dos arquivos .hem porque o Xcode e o compilador LLVM podem detectar dependências e executar compilações incrementais automaticamente. Em geral, você terá que se preocupar menos com a criação de código padronizado e descobrirá que pode obter os mesmos resultados com menos linhas.

Ainda está em dúvida? Swift é mais seguro, mais rápido e cuida do gerenciamento de memória (na maior parte!). Você sabe o que acontece no Objective-C quando você chama um método com uma variável de ponteiro não inicializada? Nada. A expressão fica inativa e é ignorada. Parece ótimo, porque não leva à falha do aplicativo; no entanto, causa vários erros e comportamento instável, pelo qual você desejará pensar em mudar de profissão. A sério. A idéia de se tornar um passeador de cães profissional brilhou com novas cores. Ao mesmo tempo, o contador Swift trabalha com valores opcionais. Você não apenas terá uma idéia melhor do que nulo pode ser e definirá condições para impedir o uso de valores nulos, mas também terá uma falha no tempo de execução se nil opcional ainda for usado, o que simplificará a depuração.O ARC (contagem automática de referência) ajuda a gerenciar melhor sua memória no Swift. No Objective-C, o ARC não funciona com C processual ou com uma API como Core Graphics.

4 - Reagir ou não Reagir? (essa é a questão)


A programação reativa funcional (FRP) é um novo sucesso. Destina-se a simplificar a compilação de operações assíncronas e fluxos de eventos / dados. Para Swift, essa é uma abstração geral da computação expressa através da interface Observable.

A maneira mais fácil de ilustrar isso é com um pequeno código. Digamos que o bebê Timmy e sua irmã Jenny querem comprar um novo console de videogame. Timmy recebe 5 euros de seus pais toda semana, o mesmo vale para Jenny. No entanto, Jenny ganha outros 5 euros entregando jornais nos finais de semana. Se ambos economizarem cada centavo, podemos verificar todas as semanas se o console está disponível! Sempre que o valor de suas economias é alterado, seu valor agregado é calculado. Se isso for suficiente, a mensagem é armazenada na variável isConsoleAttainable. A qualquer momento, podemos verificar a mensagem assinando-a.

// 
let timmySavings = Variable(5)
let jennySavings = Variable(10)

var isConsoleAttainable =
Observable
.combineLatest(timmy.asObservable(), jenny.asObservable()) { $0 + $1 }
.filter { $0 >= 300 }
.map { "\($0)    !" }

//  
timmySavings.value = 10
jennySavings.value = 20
isConsoleAttainable
   .subscribe(onNext: { print($0) }) //   

//  
timmySavings.value = 100
jennySavings.value = 200
isConsoleAttainable
   .subscribe(onNext: { print($0) }) // 300    !

Este é apenas um exemplo do que pode ser feito com o FRP, uma vez que você o domine, ele abrirá um novo mundo de possibilidades, até a adoção de uma arquitetura diferente do MVC ... Sim, sim! MVVM!
Você pode olhar para dois candidatos principais ao título de chefe do Swift FRP:


5 - Gerenciador de dependência


CocoaPods e Carthage são os gerenciadores de dependência mais comuns dos projetos Cocoa Swift e Objective-C. Eles simplificam o processo de implementação da biblioteca e a mantém atualizada.

O CocoaPods possui muitas bibliotecas criadas usando Ruby e pode ser instalado usando o seguinte comando:

$ sudo gem install cocoapods

Após a instalação, você desejará criar um Podfile para o seu projeto. Você pode executar o seguinte comando:

$ pod install

ou crie um Podfile personalizado com esta estrutura:

platform :ios, '8.0'
use_frameworks!

target 'MyApp' do
pod 'AFNetworking', '~> 2.6'
pod 'ORStackView', '~> 3.0'
pod 'SwiftyJSON', '~> 2.3'
end

Depois de criado, é hora de instalar seus novos módulos:

$ pod install

Agora você pode abrir o espaço .xcworks do seu projeto, não esqueça de importar suas dependências.

Carthage é um gerenciador de dependências descentralizado, diferente dos CocoaPods. A desvantagem disso é que está se tornando cada vez mais difícil para os usuários encontrar bibliotecas existentes. Por outro lado, essa abordagem requer menos trabalho de suporte e evita interrupções devido ao armazenamento centralizado.

Para mais informações sobre instalação e uso, confira o projeto GitHub .

6 - Armazenamento de dados


Vamos começar com a maneira mais fácil de salvar dados para seus aplicativos. NSUserDefaults , assim nomeado porque geralmente é usado para salvar os dados padrão do usuário exibidos quando o aplicativo é carregado pela primeira vez. Por esse motivo, é simples e fácil de usar, mas isso também implica algumas limitações. Um deles é o tipo de objetos que esse método aceita. Seu comportamento é muito semelhante ao Property List (Plist) , que possui a mesma restrição. Aqui estão seis tipos de objetos que eles podem armazenar:

  • NSData
  • NSDate
  • NSNumber
  • NSDictionary
  • Nsstring
  • NSArray

Para compatibilidade com Swift, o NSNumber pode aceitar os seguintes tipos:

  • UInt
  • Int
  • Flutuador
  • em dobro
  • Bool

Os objetos podem ser armazenados no NSUserDefaults da seguinte maneira (primeiro crie uma constante que armazene a chave do objeto armazenado):

let keyConstant = "objectKey"

let defaults = NSUserDefaults.standardsUserDefaults()
defaults.setObject("Object to save", objectKey: keyConstant)

Para ler um objeto de NSUserDefaults, podemos fazer o seguinte:

if let name = defaults.stringForKey(keyConstant) {
   print(name)
}

Existem vários métodos convenientes para ler e gravar em NSUserDefaults que recebem objetos específicos em vez de AnyObject.

Keychain é um sistema de gerenciamento de senhas e pode conter senhas, certificados, chaves privadas ou notas pessoais. O Keychain possui dois níveis de criptografia de dispositivo. O primeiro nível usa o código de bloqueio da tela de bloqueio como chave de criptografia. O segundo nível usa uma chave gerada e armazenada no dispositivo.

O que isso significa? Isso não é totalmente super seguro, especialmente se você não estiver usando uma senha na tela de bloqueio. Também existem maneiras de acessar a chave usada no segundo nível, pois ela é armazenada no dispositivo.

A melhor solução é usar sua própria criptografia. (Não guarde a chave no dispositivo)

CoreData- Essa é uma estrutura desenvolvida pela Apple para que seu aplicativo interaja com o banco de dados de maneira orientada a objetos. Isso simplifica o processo, reduzindo a quantidade de código e eliminando a necessidade de testar esta seção.

Você deve usar o CoreData se o seu aplicativo exigir dados persistentes, isso simplifica bastante o processo de salvá-los e permite que você não crie / teste sua própria maneira de se comunicar com o banco de dados.

7 - ColeçãoViews & TableViews


Quase todos os aplicativos possuem um ou mais CollectionViews e / ou TableViews. Saber como eles funcionam e quando usar um ou outro impedirá alterações complexas no seu aplicativo no futuro.

Os TableViews exibem uma lista de itens em uma única coluna verticalmente e são limitados apenas pela rolagem vertical. Cada item é representado por um UITableViewCell, que pode ser totalmente personalizado. Eles podem ser classificados por seções e linhas.

O CollectionViews também exibe uma lista de itens, mas eles podem ter várias colunas e linhas (por exemplo, uma grade). Eles podem ser rolados horizontalmente e / ou verticalmente, e cada elemento é representado por um UICollectionViewCell. Como UITableViewCells, eles podem ser personalizados conforme desejado e classificados por seção e linha.

Ambos têm funcionalidade semelhante e usam células reutilizáveis ​​para melhorar a mobilidade. A escolha do que você precisa depende da complexidade que você deseja ter na lista. O CollectionView pode ser usado para representar qualquer lista e, na minha opinião, é sempre a melhor escolha. Imagine que você deseja enviar uma lista de contatos. A lista é simples, você pode implementá-la com uma única coluna e selecionar um UITableView. Tudo está funcionando! Após alguns meses, seu designer decidirá que os contatos devem ser exibidos em um formato de grade, não em uma lista. A única maneira de fazer isso é alterar a implementação do UITableView para a implementação do UICollectionView. Estou tentando dizer que, embora sua lista possa ser simples e um UITableView seja suficiente se houver uma grande chance de uma alteração no design, provavelmenteé melhor implementar esta lista usando um UICollectionView.

Qualquer que seja sua escolha, é uma boa ideia criar um TableView / CollectionView genérico. Isso facilita a implementação e permite a reutilização de grandes quantidades de código.

8 - Storyboards VS Xibs VS UI Programável


Cada um desses métodos pode ser usado separadamente para criar uma interface com o usuário, mas nada impede que você os combine.

Os storyboards fornecem uma visão mais ampla do projeto que os designers irão gostar, permitindo que você veja o fluxo do aplicativo e suas janelas. A desvantagem é que, com a adição de mais janelas, as conexões se tornam mais confusas e o tempo de carregamento do Storyboard aumenta. Os problemas de mesclagem são muito mais comuns porque toda a interface do usuário está em um único arquivo. Eles também se tornam muito mais difíceis de resolver.

Xibsfornecer visualização visual de janelas ou partes de uma janela. As vantagens são a facilidade de reutilização, menos conflitos de mesclagem que os Storyboards e a facilidade de visualizar o conteúdo de cada janela.

A interface do usuário de programação oferece mais controle sobre ela, reduz a frequência de conflitos de mesclagem; se eles surgirem, eles serão mais fáceis de remover. A desvantagem é menos visualização e tempo adicional necessário para escrever.

As abordagens acima para criar uma interface de usuário variam bastante. Mas, na minha opinião subjetiva, a melhor opção é uma combinação dos três. Vários Storyboards (agora podemos alternar entre Storyboards!), Com o Xibs para qualquer objeto visual que não seja a janela principal e, finalmente, um pouco de programação para controle adicional, tão necessário em determinadas situações.

9 - Protocolos!


Na vida cotidiana, existem protocolos para que, em uma determinada situação, saibamos como responder. Suponha que você seja bombeiro e que tenha ocorrido uma emergência. Cada bombeiro deve seguir um protocolo que estabeleça os requisitos para uma resposta bem-sucedida. O mesmo se aplica aos protocolos no Swift / Objective-C.

Um protocolo define um esboço de métodos, propriedades e outros requisitos para funções especificadas. Pode ser adotado por uma classe, estrutura ou enumeração, que terá a implementação real desses requisitos.

Aqui está um exemplo de criação e uso de um protocolo:

No meu exemplo, precisarei de uma enumeração que liste os diferentes tipos de materiais usados ​​para extinguir um incêndio.

enum ExtinguisherType: String {

   case water, foam, sand

}

Em seguida, criarei um protocolo de resposta a emergências.

protocol RespondEmergencyProtocol {

   func putOutFire(with material: ExtinguisherType)

}

Agora vou criar uma classe de bombeiro que obedece ao protocolo.

class Fireman: RespondEmergencyProtocol {

    func putOutFire(with material: ExtinguisherType) {

       print("Fire was put out using \(material.rawValue).")

    }

}

Bem! E agora usamos nosso bombeiro.

var fireman: Fireman = Fireman()

fireman.putOutFire(with: .foam)

O resultado deve ser o seguinte: "O fogo foi apagado usando espuma".

Protocolos também são usados ​​na delegação. Isso permite que classes ou estruturas delegem determinadas funções a uma instância de outro tipo. Um protocolo é criado com responsabilidades delegadas para garantir que sua funcionalidade seja do tipo apropriado.
Um pequeno exemplo!

protocol FireStationDelegate: AnyObject {

func handleEmergency()

}

O corpo de bombeiros delega às medidas de resposta a emergências dos bombeiros.

class FireStation {
   weak var delegate: FireStationDelegate?

   func emergencyCallReceived() {
      delegate?.handleEmergency()
   }
}

Isso significa que o bombeiro também precisará cumprir o protocolo FireStationDelegate.

class Fireman: RespondEmergencyProtocol, FireStationDelegate {

   func putOutFire(with material: ExtinguisherType) {
      print("Fire was put out using \(material.rawValue).")
   }

   func handleEmergency() {
      putOutFire(with: .water)
   }

}

Tudo o que precisa ser feito é que o bombeiro que está nas ligações seja designado como delegado do corpo de bombeiros, e ele atenderá as chamadas de emergência recebidas.

let firestation: FireStation = FireStation()
firestation.delegate = fireman
firestation.emergencyCallReceived()

Como resultado, obtemos: "O fogo foi apagado usando a água".

10 - Curto circuitos


Será apenas sobre fechamentos Swift. Eles são usados ​​principalmente para retornar um bloco final ou com funções de alta ordem. Os blocos finais são usados, como o nome indica, para executar um bloco de código após a conclusão da tarefa.
Os fechamentos no Swift são semelhantes aos blocos em C e Objective-C.

Os fechamentos são objetos de primeira classe *, para que possam ser aninhados e passados ​​(como blocos no Objective-C).

No Swift, as funções são um caso especial de fechamento.

Fonte - fuckingswiftblocksyntax.com **

Este recurso é um ótimo local para aprender a sintaxe de fechamento.

Objetos de primeira classe - objetos que podem ser usados ​​sem restrições: atribuir a uma variável, passar / retornar de uma função, criar / destruir durante a execução do programa, etc. Mais detalhes . (daqui em diante - aprox. tradutor)
** O site não funciona, mas ainda existem fotos no waybackmachine, por exemplo .


onze - Esquema


Em resumo, os circuitos são uma maneira fácil de alternar entre configurações. Vamos começar com as informações básicas. O espaço de trabalho contém vários projetos relacionados. Um projeto pode ter vários objetivos - os objetivos determinam o produto a ser montado e o método de montagem. Além disso, um projeto pode ter várias configurações. O esquema no Xcode define a coleção de destinos para a montagem, a configuração usada durante a montagem e a coleção de testes a serem executados.

Roxo mostra um padrão possível.

12 - Testes


Se você reservar um tempo para testar seu aplicativo, estará no caminho certo. Obviamente, isso não é uma panacéia, você não pode corrigir todos os erros nem garantir que seu aplicativo estará livre de problemas; e, no entanto, acho que os profissionais superam os contras.

Vamos começar com as desvantagens do teste de unidade:

  • Maior tempo de desenvolvimento;
  • Aumente a quantidade de código.

Prós :

  • A necessidade de criar código modular (para simplificar o teste);
  • Obviamente, detectando a maioria dos erros antes do lançamento;
  • Simplificação de suporte.

Em combinação com o utilitário Ferramentas , você terá tudo para tornar o aplicativo flexível e funcionar sem erros e falhas.

Existem muitas ferramentas que você pode usar para testar seu aplicativo. Dependendo do que você deseja rastrear, você pode selecionar um ou mais deles. Talvez as ferramentas mais usadas sejam Leaks , Time Profiler e Allocations .

13 - Geolocalização


Em muitos aplicativos, algumas funções exigem a localização de um usuário. Portanto, seria bom ter uma idéia geral de como o local funciona para iOS.

Existe uma estrutura chamada Localização Principal, que permite acessar tudo o que você precisa:

A estrutura Localização principal permite determinar a localização atual ou a direção do movimento de um dispositivo. A estrutura usa o hardware disponível para determinar a posição e a direção do usuário. Você pode usar as classes e protocolos dessa estrutura para configurar e agendar eventos relacionados ao local e direção. Você também pode usar o Local Principal para rastrear movimentos nas regiões geográficas. No iOS, você também pode determinar a distância do sinalizador Bluetooth *.

* Pelo que entendi, é sobre a tecnologia iBeacon

Legal, não é? Confira a documentação da Apple e o exemplo para entender melhor os recursos da estrutura.

14 - Sequências localizáveis


O que deve ser implementado em qualquer aplicativo. Isso permite alterar o idioma, dependendo da região em que o dispositivo está localizado. Mesmo que seu aplicativo esteja em apenas um idioma, pode ser necessário adicionar novos no futuro. Se todo o texto for inserido usando cadeias localizáveis, basta adicionar a versão traduzida do arquivo Localizable.strings para o novo idioma.

O recurso pode ser adicionado ao idioma por meio do inspetor de arquivos. Para obter uma string com NSLocalizedString, você precisa escrever o seguinte:

NSLocalizedString(key:, comment:)

Infelizmente, para adicionar uma nova linha ao arquivo Localizable, isso deve ser feito manualmente. Aqui está um exemplo de estrutura:

{
"APP_NAME" = "MyApp"
"LOGIN_LBL" = "Login"
...
}

Agora em outro idioma (português), o arquivo localizado:

{
"APP_NAME" = "MinhaApp"
"LOGIN_LBL" = "Entrar"
...
}

Existem até maneiras de implementar o plural.

Sempre compartilhe o que aprendeu.

- Mestre Yoda

Espero que este artigo tenha sido útil!

All Articles