Por que eu devo ler este artigo: O artigo realizará uma abordagem histórica contextualizando o cenário de criação e desenvolvimento da primeira Apple TV, além de estabelecer um paralelo com as novas versões e os novos recursos e possibilidades de criação de conteúdo a partir da Apple Store e do novo sistema projetado para ela, o tvOS. Em seguida, será realizado um tutorial apresentando os primeiros passos na criação de um projeto no software XCode além de ensinar ao leitor como construir uma aplicação com um player de conteúdo personalizado.

O desenvolvimento de apps para a AppleTV introduz muitas oportunidades para desenvolvedores, que podem estender um aplicativo já existente ou criando um totalmente novo. Além disso, um player de conteúdo, além de ser um exemplo interessante de aprendizado, é de especial interesse para produtores de conteúdo online, como blogueiros e “YouTubers”, que podem criar o seu próprio visualizador de conteúdo personalizado na plataforma.

A AppleTV representa a culminação do sonho de Steve Jobs. Sua quarta geração abriu aos desenvolvedores de aplicativos um novo mundo ao permitir produzir apps para a plataforma. Uma vez que a proposta da AppleTV é oferecer uma nova experiência em conteúdo digital, os desenvolvedores possuem uma oportunidade única para criar aplicativos inovadores, e nesse contexto o artigo irá explorar a criação de um player de conteúdo, expondo conceitos básicos de desenvolvimento para tvOS e para sistemas da Apple em geral.

História da Apple TV

Na biografia de Steve Jobs, escrita por Walter Isaacson, o falecido CEO da Apple fala da criação de um set de televisão completamente integrado com todos dispositivos : “Ele terá a interface de usuário mais simples que você pode imaginar. Eu finalmente solucionei!”.

Jobs estava falando da AppleTV, um produto introduzido em 2006 como um trabalho em progresso chamado de iTV. Na ocasião, a Apple foi pioneira no mercado ao introduzir no iTunes novas funcionalidades e conceitos, como compra de conteúdo audiovisual e catálogos atualizados mensalmente. O conteúdo adquirido poderia ser sincronizado e visualizado no computador e em iPods, aumentando a portabilidade sem dependência de mídias físicas. Entretanto, a empresa precisava criar um produto que unificasse a nova experiência em entretenimento e conteúdo digital na televisão sem o uso de diversos controles remotos e cabos.

Assim, o iTV foi evoluindo até se tornar a AppleTV, que em sua primeira geração permitia ao usuário assistir filmes e séries, escutar sua biblioteca de músicas e exibir fotos, entre outras funcionalidades. Gerações subsequentes da AppleTV introduziram novos tipos de interação e simplicidade: a segunda geração, anunciada em 2010, foi a primeira a rodar em uma variante do iOS; a terceira geração, de 2012, dava suporte ao conteúdo de 1080p do Itunes e Netflix; e a quarta geração abriu as portas para o desenvolvimento de apps, introduzindo a AppStore para a plataforma e o tvOS SDK para desenvolvedores.

Desenvolvimento de Apps para tvOS

Ao desenvolver para a AppleTV, os desenvolvedores estarão produzindo apps no tvOS, nome dado ao sistema operacional do produto. Ele é baseado no iOS e possui muitos frameworks em comum com ele.

A IDE utilizada para desenvolvimento é o programa XCode, suportado em Mac e disponível para download no Developer Center da Apple (veja a sessão links) e na AppStore. Atualmente, o XCode está na versão 8.1 e permite o desenvolvimento em Objective-C e Swift - linguagem de programação criada pela Apple e lançada em 2014, com o objetivo de tornar o desenvolvimento em iOS mais intuitivo para novos desenvolvedores (o artigo irá utilizar essa linguagem no exemplo). O XCode possui um simulador de plataformas embutido, portanto o desenvolvedor não precisa necessariamente ter uma AppleTV para fazer seu aplicativo, apesar de ser sempre preferível testar no equipamento.

É importante notar que, para publicar aplicativos na AppleTV e nas demais plataformas da Apple, o desenvolvedor deve ter uma conta na AppStore ativada no Developer Center.

    Existem dois métodos para desenvolver apps em tvOS:
  • TVML (Television Markup Language), TVJS e TVMLKit: ideal para desenvolvedores que já possuem conteúdo em um servidor e querem apenas mostra-lo ao usuário, utiliza XML e APIs de JavaScript.
  • Custom: utiliza conceitos e ideias de desenvolvimento iOS já enraizados em outras plataformas. O artigo irá tratar deste método.

Por ter uma interface diferente do iPhone e do iPad, por exemplo, a AppleTV oferece novas oportunidades para seus desenvolvedores. Um exemplo disso é o framework TVServices, que permite aos desenvolvedores descrever o conteúdo de seu aplicativo para ser mostrado quando este é selecionado pelo usuário para ficar na “Top Shelf” (veja mais informações sobre esse framework consultando a sessão de links).

Uma limitação do tvOS é que ele não possui armazenamento local: para persistir os dados, é necessário utilizar algum serviço como o CloudKit. Além disso, o tamanho do aplicativo não pode exceder 200MB. Isso pode parecer um problema mas as APIs “On-Demand Resources” introduzidas pela Apple permitem reduzir o tamanho da aplicação ao baixar os recursos por demanda, facilitando seu encapsulamento.

Criando um player de conteúdo para a AppleTV - Código

Como já dito anteriormente no artigo, a IDE utilizada para desenvolvimento em tvOS é o programa XCode, o mesmo utilizado para plataformas iOS. Atualmente, ele é suportado apenas para Mac. O artigo usará no exemplo a linguagem de programação Swift, cujos fundamentos e conceitos em geral são reutilizáveis para o desenvolvimento em outras plataformas e sistemas Apple, como o iPhone, iPad e AppleWatch, de modo que desenvolvedores para essas plataformas não terão muita dificuldade em estender seu conhecimento para o tvOS e produzirem conteúdo para a AppleTV.

A inicialização do programa XCode é idêntica ao desenvolvimento do iOS e do watchOS, com o desenvolvedor criando um novo projeto XCode e selecionando o template inicial. No caso de nosso exemplo, o template a ser escolhido é o da tvOS, conforme figura 1:

Selecionando template para tvOS
Figura 1. Selecionando template para tvOS

Como o exemplo deste artigo terá apenas uma tela, podemos selecionar o template Single View Application na aba tvOS. Esse template irá criar um projeto básico do XCode com uma tela inicial e uma classe UIViewController para esta tela. Depois de selecionado o template, o usuário dará nome ao seu projeto e definirá um Bundle Identifier, conforme figura 2:

Selecionando template para tvOS
Figura 2. Nomeando o projeto

A recomendação da Apple para o Bundle Identifier é o formato “com.company.appname”. Esse formato não precisa ser seguido, porém é muito importante que ele seja único em toda AppStore, uma vez que ele servirá para conectar seu projeto no XCode com a submissão do aplicativo na loja, e alterá-lo depois de inicializado não é um processo trivial. Assim, o desenvolvedor deve criar, nessa etapa, um identificador único para seu projeto, evitando erros no futuro.

O nome da organização (Organization Name) deverá ser a empresa ou local em que ele trabalha, estando relacionado com os outros identificadores.

O XCode utiliza o conceito de Storyboard, uma representação gráfica das telas do aplicativo (as chamadas views). Existem vários tipos diferentes de classes de telas que podem ser instanciadas, como uma TableView, que é uma tela apropriada para mostrar listas de itens), e uma CollectionView, tela para mostrar coleções de itens.

A classe que faz a gestão de uma view é chamada de UIViewController, relacionada ao elemento gráfico ViewController e estendida para outras classes de views. Por exemplo, para criar uma TableView em uma tela inteira, podemos instanciar uma UITableViewController, que herda as características da UIViewController, possuindo também seus próprios métodos para configurar a lista que será exibida na view. Um exemplo análogo pode ser inferido para cada tipo de view disponível. Para saber mais sobre ViewControllers, acesse online as guidelines da Apple sobre o assunto (veja a sessão de links para maiores informações).

O Storyboard do XCode pode ser acessado clicando na aba Main.storyboard. Inicialmente, ele possui uma tela instanciada na classe UIViewController, conforme figura 3:

Selecionando template para tvOS
Figura 3. Storyboard inicial do Xcode, com uma tela instanciada para a classe ViewController, como indicado no lado esquerdo da figura.

Em outras palavras, uma vez que o template para Single View Application é selecionado, o XCode irá criar no Storyboard uma view do tipo ViewController, e irá associar uma classe UIViewController para essa view. Com o projeto configurado, a primeira coisa a se fazer é criar a classe que vamos utilizar para construir nosso player. Para criar uma nova classe no XCode, selecione na aba superior New->File, conforme figura 4:

Selecionando template para tvOS
Figura 4. Criando uma nova classe no XCode

Na tela que se abrirá, o desenvolvedor seleciona o tipo de arquivo que deseja criar. No caso de view, o arquivo Cocoa Touch Class deve ser selecionado (se quisermos criar uma classe própria a ser utilizada, podemos selecionar um arquivo do tipo Swift File e criar nossa classe a partir dele), e em seguida a classe que deseja ser criada é selecionada no campo “Subclass of”. O desenvolvedor pode utilizar classes prontas do XCode, como as já mencionadas UITableViewController e UICollectionViewController. Neste exemplo, criaremos uma classe do tipo AVPlayerViewController, específica para nossos objetivos de criar um player, chamada deVideoPlayerViewController conforme figura 5:

Selecionando template para tvOS
Figura 5. Instanciando a classe VideoPlayerViewController

Antes de utilizar a classe, devemos importar o AVKit, que assim como outros pacotes da Apple como o MapKit ou HealthKit, nos permitirão usar classes e métodos específicos. A declaração destes pacotes é feita como a primeira coisa do código. Além disso, iremos inicializar variáveis com a url do vídeo que queremos mostrar, o nome da imagem que servirá como watermark e o tamanho da view que conterá essa watermak (no caso, a inclusão da watermark, ou marca d’agua, é opcional; o desenvolvedor pode escolher se o player exibirá essa imagem ou não).

Também, iremos definir o método que é chamado quando a view termina de carregar, chamado de viewDidLoad(). Na verdade, o XCode e a linguagem Swift possuem métodos para tratar do ciclo de vida de suas views. O método viewDidLoad(), por exemplo, é chamado sempre que a view acaba seu carregamento, como já dito. Outros métodos são chamados em diversos momentos durante o ciclo de vida das views. O método viewWillAppear(), por exemplo, é chamado logo antes da view aparecer, enquanto o método viewDidAppear() é chamado logo depois (para maiores informações sobre o ciclo de vida de views, cheque as orientações da Apple sobre o assunto, disponíveis na sessão de links). O trecho de código com as declarações citadas pode ser visto na Listagem 1:

Listagem 1. Estado inicial da classe VideoPlayerViewController

 

import UIKit
import AVKit

class VideoPlayerViewController: AVPlayerViewController {

 01  let overlay = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
 02  let watermark = "your_image_name"
 03  var url = “http://www.your_url_string”
 04   override func viewDidLoad() {
 05     super.viewDidLoad()
 06     setVideoPlayer()
                         }

                 }

01 – Variável que armazena e customiza o tamanho da view que irá conter a watermark, 
     de acordo com a preferência do desenvolvedor.
02 – Nome da imagem da watermark, que será adicionada ao projeto posteriormente.
03 – URL com o vídeo que o player irá reproduzir. 
04 – Assim como no desenvolvimento para outras plataformas Apple, o método viewDidLoad()
     é chamado quando a view acaba de carregar. O termo Override serve para sobrescrever 
     o comportamento inicial do método, conforme visto nos itens 05 e 06.
05 – Declaração para chamar o comportamento do método viewDidLoad normal, sem sobrescrição.
06 – Método que iremos utilizar para configurar o player, a ser implementado.
 

Como pode-se perceber, o código acima utiliza a notação “let” antes do nome. A linguagem Swift, ao contrário das outras linguagens de programação, permite a definição de constantes, que são as “let”. Uma let não muda de valor durante toda a execução do código, podendo ser considerada constante. Nesse artigo usaremos o termo variáveis para se referir tanto a “let” como a “var”, mas desenvolvedores devem conhecer a diferença entre os dois tipos de declaração.

O programa XCode faz compilação em tempo real, ou seja, ele pode fornecer alertas de erros se há algo errado no código. Nesse caso, por exemplo, ele acusará um erro pois ainda não implementamos o método setVideoPlayer. Para isso, iremos criar uma extensão da classe VideoPlayerViewController, adicionando-a abaixo da declaração da classe conforme Listagem 2.

Listagem 2. Listagem com referências de linhas


01 - typealias VideoPlayer = VideoPlayerViewController
02 - extension VideoPlayer {
     func setVideoPlayer() {
03 - overlay.addSubview(UIImageView(image: UIImage(named: watermark)))
04 - contentOverlayView?.addSubview(overlay)
05 - player = AVPlayer(url: URL(string: url)!)
06 - player?.play()
       }
   }
 

01 – Afirma que a extensão será para a classe VideoPlayerController.
02 – Declaração da extensão.
03 – Configura a view que terá a marca d’agua (ela será uma subview de overlay do tipo UIImageView,
     tipo utilizado pela linguagem Swift para mostrar imagens).
04 – Adiciona a subview com a marca d’agua
05 – Configura o player, que será um objeto do tipo AVPlayer e que recebe como 
     parâmetro a url do vídeo a ser reproduzido.
06 – Comando de Play

Com o código já configurado, podemos criar a lógica por trás das telas.

Criando um player de conteúdo para a AppleTV - Telas

Primeiramente, vamos criar no Storyboard uma tela onde nosso player será iniciado. Para isso, selecionamos no canto inferior direito o tipo AVKit Player View Controller, uma subclasse da UIViewController, e a arrastamos para dentro do Storyboard (essa é a maneira comum de se criar telas utilizando o Storyboard; para criarmos uma TableView, por exemplo, podemos selecionar o item TableViewController do canto inferior direito e arrastá-lo para dentro do Storyboard).

Para o XCode reconhecer que essa view estará relacionada com a classe VideoPlayerViewController, nós adicionamos o nome dela no canto superior direito, conforme figura 6:

Selecionando template para tvOS
Figura 6. Criando uma view AVKit Player e instanciando a classe VideoPlayerViewController

Esse ato pode ser considerado como uma instanciação da classe, ou seja, ao nomearmos a classe da tela, estamos dizendo que essa tela irá ter as características, atributos e métodos definidos na classe. Agora, iremos criar um botão na tela inicial. Para tal, assim como na criação de uma view, selecionamos o tipo “Button” no canto inferior direito da tela e o arrastamos para dentro do Storyboard, conforme figura 7:

Selecionando template para tvOS
Figura 7. Criando um Button na tela inicial

O XCode utiliza o conceito de “segue” para mudança de telas. Ele pode ser configurado programaticamente ou utilizando o próprio Storyboard (como será implementado no artigo). Para criar segues no XCode utilizando o Storyboard, selecionamos o botão e, pressionando a tecla Control, arrastamos a linha gerada para dentro da tela AV Player View Controller. Então, podemos selecionar que tipo de transição de telas queremos (o tipo Present Modally, por exemplo, irá apresentar de forma modal). Para esse exemplo, vamos selecionar o tipo Show, pois só queremos mostrar a tela nova.

Com a segue criada, podemos chama-lo com um identificador no Storyboard. Para fazer isso, colocamos o nome desejado no campo “Identifier”, conforme figura 8:

Selecionando template para tvOS
Figura 8. Nomeando o segue

Agora, precisamos definir o comportamento do button. Para isso, iremos criar outlets, que são a forma do XCode de relacionar o Storyboard com o código. Selecionando o símbolo de dois círculos no canto superior direito, o programa divide o Storyboard com nosso código. Podemos, então, pressionar a tecla Control e arrastar a linha gerada para dentro do código.

Iremos criar uma connection do tipo outlet chamada de playButton, e uma connection do tipo Action chamada de playVideo - a diferença é que uma outlet é como uma variável, onde podemos acessar propriedades do button, e uma action indica o comportamento do button -, conforme figura 9:

Selecionando template para tvOS
Figura 9. Criando uma action para o button

Vamos também declarar uma variável contento o identificador que demos para o segue, conforme Listagem 3:

Listagem 3. Listagem com declaração da constante segueID

 let segueID = “showAVPlayer” 

Dentro da action, iremos adicionar o método disponível em Swift chamado performSegue, indicando que queremos chamar o segue com uma id específica, conforme Listagem 4 e figura 10:

Listagem 4. Chamando o segue criado

 self.performSegue(withIdentifier: segueID, sender: self) 
Selecionando template para tvOS
Figura 10. Criando o método performSegue

Com as telas configuradas, podemos passar para a última parte do exemplo, que é configurar a url e a watermark. Para termos uma url do YouTube aceita pelo XCode, é necessário baixar a extensão Video URL Parser do Google Chrome (veja sessão de links para informações sobre onde fazer o download). Com a extensão adicionada ao navegador, podemos abrir o YouTube e selecionando o símbolo da extensão e, em seguida, a seta vermelha, obtemos a url desejada, conforme figura 11 e 12:

Selecionando template para tvOS
Figuras 11. Obtendo a url do video a ser reproduzido
Selecionando template para tvOS
Figuras 12. Obtendo a url do video a ser reproduzido

Agora, copiamos essa url e colamos ela no código da classe VideoPlayerViewController, no lugar de http://www.your_url_string, conforme listagem 5:

Listagem 5. Adicionando a url do video que queremos tocar

 var url = "https://r19---sn-aigllnll.googlevideo.com/videoplayback?nh=IgpwcjAzLmxocjE0
    KgkxMjcuMC4wLjE&itag=18&mime=video%2Fmp4&id=o-AE5TjguVbYmiHACo4tOVmcIn6jlTC79Lh7N8TV4QhtHf&
    expire=1480062992&pl=19&requiressl=yes&sparams=dur%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%
    2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cnh%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cupn%2Cexpire&
    dur=1237.879&mm=31&mn=sn-aigllnll&ip=78.157.200.133&key=yt6&signature=B2F9899AE7CBFCF6BE2BB3B
    5C3F77E8710D7F689.87FB1E45040CB6DEC4C4FDC4477ACC33549E5AEC&mt=1480041137&mv=m&initcwndbps=164
    2500&ipbits=0&ms=au&lmt=1479946892438005&upn=1B2jk8YYmCw&source=youtube&ratebypass=yes" 

Por último, vamos importar a imagem que será nossa watermark. Para isso, selecionamos a imagem desejada dentro de nosso computador e incluímos ela dentro da pasta Assets.xcassets, local que o XCode utiliza para armazenamento das imagens que serão utilizadas na aplicação (incluindo o ícone do App e Top Shelf Image, colocados na pasta “App Icon & Top Shelf Image”), conforme figura 13:

Selecionando template para tvOS
Figura 13. Importando imagem para o XCode

Na classe VideoPlayerViewController, substituímos “your_image_name” pelo nome da imagem, como por exemplo “watermark”, conforme listagem 6.

Listagem 6. Adicionando nome da imagem da marca d’agua

 let watermark = “watermark”

É importante notar que, ao incluirmos a imagem na pasta Assets, só precisamos passar seu nome como uma String para cria-la. O código final da classe termina conforme listagem 7 e figura 14:

Selecionando template para tvOS
Figura 14. Código final da classe VideoPlayerViewController

Listagem 7. Código completo da clase VideoPlayerViewController

 
import UIKit
import AVKit

class VideoPlayerViewController: AVPlayerViewController {
   
   let overlay = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
   let watermark = "your_image_name"
   var url = "https://r19---sn-aigllnll.googlevideo.com/videoplayback?nh=IgpwcjAzLmxocj
   E0KgkxMjcuMC4wLjE&itag=18&mime=video%2Fmp4&id=o-AE5TjguVbYmiHACo4tOVmcIn6jlTC79Lh7N8
   TV4QhtHf&expire=1480062992&pl=19&requiressl=yes&sparams=dur%2Cid%2Cinitcwndbps%2Cip%
   2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cnh%2Cpl%2Cratebypass%2Crequiressl
   %2Csource%2Cupn%2Cexpire&dur=1237.879&mm=31&mn=sn-aigllnll&ip=78.157.200.133&key=yt6
   &signature=B2F9899AE7CBFCF6BE2BB3B5C3F77E8710D7F689.87FB1E45040CB6DEC4C4FDC4477ACC33
   549E5AEC&mt=1480041137&mv=m&initcwndbps=1642500&ipbits=0&ms=au&lmt=1479946892438005&
   upn=1B2jk8YYmCw&source=youtube&ratebypass=yes"
   
   override func viewDidLoad() {
       super.viewDidLoad()
       setVideoPlayer()
   }

}

typealias VideoPlayer = VideoPlayerViewController
extension VideoPlayer {
   
   func setVideoPlayer() {

       overlay.addSubview(UIImageView(image: UIImage(named: watermark)))
       contentOverlayView?.addSubview(overlay)
       
       player = AVPlayer(url: URL(string: url)!)
       
       player?.play()
   }
}

Como já dito, o XCode possui um simulador para as plataformas Apple. Para rodá-lo, basta clicar no botão de play no canto superior esquerdo, e você verá seu player funcionando.

Selecionando template para tvOS
Figuras 15. Resultado final: player funcionando

As telas geradas serão uma representação daquelas criadas no seu Storyboard e com o botão Option é possível simular o clique no controle. Além disso, o simulador para a AppleTV disponibiliza uma simulação do controle remoto do produto. Clicando no botão na primeira tela, o vídeo selecionado irá iniciar, conforme figuras 15 e 16:

Selecionando template para tvOS
Figuras 16. Resultado final: player funcionando