Em 2008, a Apple anunciou e lançou o iPhone SDK 2.0. Este evento deu início a outra revolução no desenvolvimento de software e, assim, nasceu uma nova geração de desenvolvedores, que agora são reconhecidos como desenvolvedores iOS .
javascript criar data a partir do carimbo de data / hora
Muitos desses desenvolvedores nunca haviam usado Objective-C antes e esse foi o primeiro desafio que a Apple teve para eles. Apesar de uma sintaxe desconhecida e gerenciamento manual de memória, foi um sucesso imenso, ajudando a preencher a App Store com dezenas de milhares de aplicativos. A Apple melhorou continuamente o Objective-C a cada novo lançamento, adicionando blocos e literais ( literais ), adicionando manipulação de memória simplificada com contagem automática de referência e muitos outros recursos que indicam uma linguagem de programação moderna.
E depois de seis anos trabalhando e melhorando o Objective-C, a Apple decidiu desafiar os desenvolvedores novamente. Mais uma vez, os desenvolvedores iOS terão que aprender uma nova linguagem de programação: Rápido . O Swift remove o gerenciamento inseguro de ponteiros e apresenta recursos novos e impotentes, enquanto mantém a interação com Objective-C e C.
O Swift 1.0 é uma plataforma de desenvolvimento forte e estável, que certamente evoluirá de maneiras interessantes nos próximos anos. É o momento perfeito para começar a explorar esta nova linguagem, pois é obviamente o futuro do desenvolvimento iOS.
O objetivo deste tutorial é fornecer para desenvolvedores Objective-C uma visão geral rápida dos novos recursos da linguagem Swift, ajudando você a dar o próximo passo e começar a abraçar o Swift em seu trabalho diário. Não vou gastar muito tempo explicando Objective-C, vou assumir que você está familiarizado com o desenvolvimento do iOS.
Para começar a explorar o Swift, o que você precisa é baixe o XCode 6 na App Store e criar uma área de jogo para fazer experiências. Todos os exemplos mencionados neste artigo foram feitos dessa forma.
Site da Apple Swift é a melhor referência para aprender sobre programação Swift. Você verá que é muito valioso, e até que você esteja totalmente atualizado com o desenvolvimento Swift Acho que você vai voltar aqui com frequência.
Para declarar uma variável em Swift, use a palavra-chave var
.
var x = 1 var s = 'Hello'
Você notará que as duas variáveis s
e x
eles são de tipos diferentes. x
é um número inteiro, enquanto 's' é uma sequência de caracteres. Swift é um tipo de linguagem seguro e deduzirá tipos de variáveis a partir do valor atribuído. Se quiser que seu código seja mais legível, você pode opcionalmente anotar o tipo de variável:
var y: Int y = 2
As constantes são semelhantes, mas são declaradas usando let
em vez de var
. Você não precisa saber o valor de uma constante em tempo de compilação, mas deve atribuir um valor a ela exatamente uma vez.
let c1 = 1 // Constante conocida al momento de la compilación var v = arc4random() let c2 = v // Constante conocida solo en momento de ejecución
Como o nome indica, eles são imutáveis, portanto, o código a seguir causará um erro em tempo de compilação.
let c = 1 c = 3 // error
Outros tipos também podem ser declarados como constantes. Por exemplo, o código a seguir declara uma matriz como uma constante e, se você tentar modificar qualquer um dos elementos, o compilador Swift relatará um erro:
var arr2 = [4, 5, 6] arr2[0] = 8 print (arr2) // [8, 5, 6] let arr = [1, 2, 3] a[0] = 5 // error
As constantes precisam ser inicializadas quando estão sendo declaradas, assim como as variáveis precisam ser inicializadas antes de usá-las. Então, onde está o equivalente nil
de Objective-C? Swift apresenta valores opcionais . Os valores opcionais podem ter um valor ou ser nil
. Se você olhar o código a seguir, verá que x
foi atribuído como valor Opcional
de 2014
. Isso significa que o compilador Swift sabia que x
poderia ser nil
.
var s = '2014' var x = s.toInt() print(x) // Optional(2014)
Se você fizer uma alteração neste código e atribuir o valor 'abc'
para s
, que não pode ser convertido em um número inteiro, você notará que x
agora é um nil
.
var s = 'abc' var x = s.toInt() print(x) // nil
O tipo de retorno do toInt()
é Int?
, que é um Opcional int . Vamos tentar chamar uma função padrão em x
:
var x = '2014'.toInt() print(x.successor()) // error
O compilador relata um erro, pois x
é um opcional e pode ser nulo . Devemos tentar x
primeiro, e certifique-se de que sucessor
é invocado em um número real, e não em um valor nil
:
var x = '2014'.toInt() if x != nil { print(x!.successor()) // 2015 }
Tenha em mente que devemos desembrulhar x
adicionar um ponto de exclamação (!) . Quando nos certificamos de que x
contém um valor, podemos acessá-lo. Caso contrário, obteremos um erro de tempo de execução. Também podemos fazer o que o Swift chama ligação opcional , convertendo assim a variável opcional em não opcional
let x = '123'.toInt() if let y = x { print(y) }
O código para if
só será executado se x
tem um valor e é atribuído a y
. Observe que não precisamos desembrulhar y
, seu tipo não opcional, pois sabemos que x
não é nil
.
Confira o tutorial do Swift da Apple, onde você pode ler em detalhes sobre recursos opcionais e interessantes como encadeamento opcional
Em Objective-C, uma string de formatação geralmente é feita com o método stringWithFormat:
:
NSString *user = @'Gabriel'; int days = 3; NSString *s = [NSString stringWithFormat:@'posted by %@ (%d days ago)', user, days];
Swift tem um recurso chamado Interpolação de string que faz o mesmo, mas é mais compacto e fácil de ler:
let user = 'Gabriel' let days = 3 let s = 'posted by (user) (days) ago'
Você também pode usar expressões:
let width = 2 let height = 3 let s = 'Area for square with sides (width) and (height) is (width*height)'
Para saber mais sobre a interpolação de strings Swift, vá para Aqui .
A definição de função em Swift é diferente de C. Um exemplo de definição de função é o seguinte:
func someFunction(s:String, i: Int) -> Bool { ... // code }
Funções Swift são tipos de primeira classe . Isso significa que você pode atribuir funções a variáveis, passá-los como parâmetros para funções ou torná-los tipos de retorno:
func stringLength(s:String) -> Int { return countElements(s) } func stringValue(s:String) -> Int { if let x = s.toInt() { return x } return 0 } func doSomething(f:String -> Int, s:String) -> Int { return f(s).successor() } let f1 = stringLength let f2 = stringValue doSomething(f1, '123') // 4 doSomething(f2, '123') // 124
Novamente, o Swift infere os tipos de f1
e f2
(String
-> Int
), embora pudéssemos tê-los definido explicitamente:
let f1:String -> Int = stringLength
As funções também podem retornar outras funções:
func compareGreaterThan(a: Int, b: Int) -> Bool { return a > b } func compareLessThan(a: Int, b: Int) -> Bool { return a (Int, Int) -> Bool { if greaterThan { return compareGreaterThan } else { return compareLessThan } } let f = comparator(true) println(f(5, 9))
Um guia para funções em Swift está localizado Aqui .
Enums em Swift são muito mais poderosos do que em Objective-C. Como o Swift o estrutura, eles podem ter métodos e são passados como valores:
enum MobileDevice : String { case iPhone = 'iPhone', Android = 'Android', WP8 = 'Windows Phone8', BB = 'BlackBerry' func name() -> String { return self.toRaw() } } let m = MobileDevice.Android print(m.name()) // 'Android'
Ao contrário do Objective-C, os enums do Swift podem atribuir strings, caracteres ou flutuantes como valores para cada membro, exceto inteiros. O método conveniente toRaw()
retorna o valor atribuído a cada membro.
Enumerações também podem ser parametrizadas:
enum Location { case Address(street:String, city:String) case LatLon(lat:Float, lon:Float) func description() -> String { switch self { case let .Address(street, city): return street + ', ' + city case let .LatLon(lat, lon): return '((lat), (lon))' } } } let loc1 = Location.Address(street: '2070 Fell St', city: 'San Francisco') let loc2 = Location.LatLon(lat: 23.117, lon: 45.899) print(loc1.description()) // '2070 Fell St, San Francisco' print(loc2.description()) // '(23.117, 45.988)'
Você pode encontrar mais informações sobre enums Aqui .
As tuplas agrupam vários valores em um único valor composto. Os valores dentro de uma tupla podem ser de qualquer tipo e não precisam ser do mesmo tipo.
let person = ('Gabriel', 'Kirkpatrick') print(person.0) // Gabriel
Você também pode nomear elementos individuais de tupla:
let person = (first: 'Gabriel', last: 'Kirkpatrick') print(person.first)
Tuplas são extremamente convenientes como tipos de retorno para funções que precisam retornar mais de um valor:
func intDivision(a: Int, b: Int) -> (quotient: Int, remainder: Int) { return (a/b, a%b) } print(intDivision(11, 3)) // (3, 2) let result = intDivision(15, 4) print(result.remainder) // 3
Ao contrário de Objective-C, o Swift suporta a localização de padrões na instrução case ou switch case:
let complex = (2.0, 1.1) // real and imaginary parts switch complex { case (0, 0): println('Number is zero') case (_, 0): println('Number is real') default: println('Number is imaginary') }
No segundo caso, não nos importamos com a parte verdadeira do número, então usamos um _
para que possa corresponder a qualquer coisa. Você também pode verificar se existem condições adicionais em cada caso. Para isso, você precisa juntar os valores padrão:
let complex = (2.0, 1.1) switch complex { case (0, 0): println('Number is zero') case (let a, 0) where a > 0: println('Number is real and positive') case (let a, 0) where a <0: println('Number is real and negative') case (0, let b) where b != 0: println('Number has only imaginary part') case let (a, b): println('Number is imaginary with distance (a*a + b*b)') }
Observe como precisamos combinar apenas os valores que vamos usar na comparação ou no caixa de troca .
Você pode ler mais sobre tuplas Aqui .
Ao contrário de Objective-C, Swift não exige que você crie interface separada e documentos de implementação para classes e estruturas personalizadas. Conforme você aprende sobre Swift, você aprenderá a definir uma classe ou estrutura em um único documento, e a interface externa para aquela classe ou estrutura é automaticamente disponibilizada para uso por outro código.
As definições de classe são muito simples:
class Bottle { var volume: Int = 1000 func description() -> String { return 'This bottle has (volume) ml' } } let b = Bottle() print(b.description())
Como pode ver, declaração e implementação estão no mesmo documento . O Swift não usa mais um cabeçalho ou documentos de implementação. Vamos adicionar uma tag ao nosso exemplo:
class Bottle { var volume: Int = 1000 var label:String func description() -> String { return 'This bottle of (label) has (volume) ml' } }
O compilador reclamará, já que o rótulo é uma variável não opcional e não conterá um valor quando um Bottle for instanciado. Precisamos adicionar um inicializador:
class Bottle { var volume: Int = 1000 var label:String init(label:String) { self.label = label } func description() -> String { return 'This bottle of (label) has (volume) ml' } }
Ou podemos usar o tipo Opcional
para uma propriedade, que não precisa ser inicializada. No exemplo a seguir, convertemos para volumen
a Número entero Opcional
:
class Bottle { var volume: Int? var label:String init(label:String) { self.label = label } func description() -> String { if self.volume != nil { return 'This bottle of (label) has (volume!) ml' } else { return 'A bootle of (label)' } } }
A linguagem Swift também tem structs
, mas eles são muito mais flexíveis do que em Objective-C. O seguinte tutorial de código define um struct
:
struct Seat { var row: Int var letter:String init (row: Int, letter:String) { self.row = row self.letter = letter } func description() -> String { return '(row)-(letter)' } }
Como as classes em Swift, as estruturas podem ter métodos, propriedades, inicializadores e estar em conformidade com os protocolos. A principal diferença entre classes e estruturas é que classes são passadas por referência, enquanto estruturas são passadas por valor .
Este exemplo demonstra a passagem das classes por referência:
let b = Bottle() print(b.description()) // 'b' bottle has 1000 ml var b2 = b b.volume = 750 print(b2.description()) // 'b' and 'b2' bottles have 750 ml
Se tentarmos fazer algo semelhante com struct
, você notará que as variáveis são passadas com valores:
var s1 = Seat(row: 14, letter:'A') var s2 = s1 s1.letter = 'B' print(s1.description()) // 14-B print(s2.description()) // 14-A
Quando devemos usar struct
e quando usamos class
? Como em Objective-C e C, use structs quando precisar agrupar alguns valores e esperar que eles sejam copiados em vez de cores referenciadas ou RGB.
A instância de uma classe é tradicionalmente conhecida como um objeto. No entanto, as classes e estruturas do Swift são muito mais próximas em funcionalidade do que em outras linguagens, e muitas funcionalidades podem ser aplicadas a instâncias de estrutura de tipo ou classe. Por esse motivo, o termo mais geral usado em referência ao Swift é instancia
, que se aplica a qualquer um dos dois.
Aprenda o básico das classes e estruturas do Swift Aqui .
Como vimos anteriormente, as propriedades em Swift são declaradas com a palavra-chave var
dentro da definição de uma classe ou estrutura. Também podemos declarar com a instrução let
.
struct FixedPointNumber { var digits: Int let decimals: Int } var n = FixedPointNumber(digits: 12345, decimals: 2) n.digits = 4567 // ok n.decimals = 3 // error, decimals is a constant
Observe também que as propriedades da classe são fortemente referenciadas, a menos que você use o prefixo weak
como uma palavra-chave. No entanto, existem algumas sutilezas com propriedades não opcionais de fraco, então leia o Capítulo Contabilidade de Referência Automática no Guia Swift da Apple.
As propriedades calculadas não armazenam um valor. Em vez disso, eles fornecem um getter e um setter opcional para recuperar e definir outras propriedades e valores indiretamente.
O código a seguir fornece um exemplo de um valor calculado sign
:
enum Sign { case Positive case Negative } struct SomeNumber { var number:Int var sign:Sign { get { if number <0 { return Sign.Negative } else { return Sign.Positive } } set (newSign) { if (newSign == Sign.Negative) { self.number = -abs(self.number) } else { self.number = abs(self.number) } } } }
Também podemos definir propriedades somente leitura apenas implementando um getter:
struct SomeNumber { var number:Int var isEven:Bool { get { return number % 2 == 0 } } }
Em Objective-C, as propriedades geralmente são apoiadas por uma variável de instância, explicitamente declarada ou criada automaticamente pelo compilador. Por outro lado, em Swift, uma propriedade não tem uma variável de instância correspondente . Ou seja, o armazenamento de apoio de uma propriedade não pode ser acessado diretamente. Suponha que temos isso em Objective-C:
// .h @interface OnlyInitialString : NSObject @property(strong) NSString *string; @end // .m @implementation OnlyInitialString - (void)setString:(NSString *newString) { if (newString.length > 0) { _string = [newString substringToIndex:1]; } else { _string = @''; } } @end
Como as propriedades calculadas do Swift não têm um armazenamento de apoio, precisamos de algo assim:
class OnlyInitialString { var initial:String = '' var string:String { set (newString) { if countElements(newString) > 0 { self.initial = newString.substringToIndex(advance(newString.startIndex, 1)) } else { self.initial = '' } } get { return self.initial } } }
As propriedades são explicadas com mais detalhes Aqui
Existem muitas coisas mais importantes e novas para aprender em Swift, como programação genérica, interação com bibliotecas Objective-C, encerramentos, encadeamento opcional e sobrecarga do operador. Um único tutorial não pode descrever completamente uma nova linguagem, mas não tenho dúvidas de que muito mais será escrito sobre a programação Swift. Porém, eu acho que isso Leitura rápida ajudará muitos desenvolvedores de Objective-C, que não encontraram tempo, nem aprenderam detalhes sobre a linguagem Swift, a começar e deixar que o pássaro Swift o leve a novas alturas.