Ao criar aplicações mobile, uma das principais funcionalidades que o desenvolvedor pode e deve explorar é a notificação. Basicamente, temos dois tipos de notificação:

  • Notificações Locais:
    São armazenadas no próprio sistema operacional do aparelho e não dependem de webservices ou conexão com a internet.

  • Notificações Remotas(Push Notifications):
    Exigem que o desenvolvedor implemente um webservice que envie essas mensagens para um PNS(Push Notification Service), em nosso caso será APNS(Apple Push Notification Service) que encaminhará essa mensagens para os devices.

    Precisei implementar notificações remotas na minha ultima aplicação iOS e sinto que provavelmente precisarei desse post para refrescar a memória. Nosso foco será apenas em Notificações remotas, pois estou preparando outro post exclusivamente sobre notificações locais.

Pré-requisitos

  • Xcode 6.4 ou superior
  • Conta de desenvolvedor Apple
  • iPhone, iPad ou iPod (O Simulador não permite testar notificações remotas)
  • iOS 8 ou superior

Passo-a-Passo

Para alcançar nosso objetivo, precisamos seguir os seguintes passos:

  • Preparar nossa aplicação iOS para receber notificações
  • Enviar DeviceToken para aplicação web(cada device possui um token unico para cada aplicação)
  • configurar certificados SSL no painel de adminstração da Apple
  • enviar notifições da aplicação web
  • Preparar nossa Aplicação Rails para enviar notificações usando a gem APNS

Passo 1: Aplicações iOS

Para enviar notificações, primeiramente precisamos pedir permissão ao usuário. podemos fazer isso em poucas linha de codigo:

1
2
3
4
5
6
7
8
9
10
11
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Register for push notifications
let notificationTypes: UIUserNotificationType = .Badge | .Sound | .Alert
let notificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
// Ask user permission
UIApplication.sharedApplication().registerForRemoteNotifications()
return true
}

Assim que nossa aplicação iniciar, irá solicitar ao usuario permissão para notificações remotas. Agora que temos a permissão, precisamos enviar o device token para nossa aplicações web.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
// Create and Store the device token on local database and send
// Token to backend API
// 1:
// remove "<" and ">" from the string
let trimEnds = token.description.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>"))
// 2:
// remove spaces
let cleanToken = trimEnds.stringByReplacingOccurrencesOfString(" ", withString: "", options: nil)
//Send the cleanToken to your WebServer(network call)
}
// If the user does not allow push notifications, this method will be called
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
NSLog("Failed to get token. Error: %@", error)
}
  • Atenção: Devemos lembrar que o device token pode mudar a qualquer momento. A apple pode gerar um novo token a qualquer momento para o device do usuario, logo devemos sempre manter esse token atualizado em nossa Aplicação Rails. Não vou entrar em detalhes de como fazer isso, pois não é o foco desse post, mas se você está comunicando sua aplicação iOS com um Backend, provavelmente já saberá como fazer um request HTTP para atualizar esse token no seu servidor.

Passo 2: Solicitar certificados SSL

A primeira coisa que precisamos fazer é criar um App ID para nossa aplicação iOS. Para isso iremos no Apple App ID

  • Atenção: Precisamos criar um “Explicit App ID” para fazer uso de push notifications.

Ao preecher o formulario, lembre-se de dar um check em “push notifications” na parte de “App Services”. Apos preencher o formulario e submeter, va para a lista de App ID, selecione o App ID que acabou de criar e click em edit para gerarmos os certificados.

Certificate generation

Esses certificados serão usados em nossa Aplicação Rails para se comunicar com Apple Push Notification Service(APNS). Click em create certificate tanto para Development SSL Certificate quando para Production SSL Certificate pois precisamos de um certificado para cada environment. Siga as instruções de criação para cada certificado e faça o download do Development SSL Certificate e do Production SSL Certificate. Após o download, click duas vezes sobre cada um para adiciona-los ao Keychain Access.

Passo 3: Exportar SSL Certificates do Keychain para uso em nossa Aplicação Rails

Agora que temos nossos certificados, tanto para desenvolvimento quanto para produção, precisamos gerá-los em um formato compativel com nosso WebService. Podemos fazer isso da seguinte forma.

  • 1: Abra o Keychain;
  • 2: Selecione “Certificates”;
  • 3: click com o botão direito sobre o certificado que importamos onde terá o nome parecido como: Apple Development Push Services: com.yourname.appname e click em Export
  • 4: Na caixa de diálogo antes de salvar, selecione o formato como Personal Information Exchange(.p12)

    Exporting Certificates

Repita os mesmos passos para o production certificate.

Passo 4: Converter certifados para .pem

Baseado na documentação da gem APNS, abriremos o terminal e executaremos o seguinte comando dentro da pasta onde estão os arquivos .p12:

1
2
3
4
5
# Development
$ openssl pkcs12 -in development.p12 -out development.pem -nodes -clcerts
# Production
$ openssl pkcs12 -in production.p12 -out production.pem -nodes -clcerts

Passo 5: Instalar gem APNS na nossa Aplicação Rails

Partindo do pressuposto que já possuímos nossa aplicação Rails com um Model criado para armazenar o token do device, iremos apenas habilitar o envio de Push Notifications em um controller. Em nosso exemplo, simularei a criação de novos posts para um blog fictício que possui uma aplicação iOS onde a cada novo post, uma notificação é enviada para todos os usuários cadasdastrados que possuem o iOS App.

Primeiro, adicionaremos a gem em nosso Gemfile:

1
gem "apns"

Agora, em seu terminal, execute:

1
$ bundle install

Passo 6: Configurar Environment (Development e Production)

Enquanto nosso iOS App estiver em desenvolvimento, precisamos enviar push notifications apartir de nosso WebServer para o host gateway.sandbox.push.apple.com usando o development.pem certificate. Porém, após ter submetido seu app para App Store, precisamos enviar push notifications para gateway.push.apple.com usando o production.pem certiticate.

Primeiro, copie os arquivos development.pem e production.pem para sua aplicação Rails. Precisaremos do Path desses arquivos para configurar o APNS. crie o arquivo config/initializers/apns.rb e insira o codigo abaixo:

1
2
3
4
5
6
7
8
9
10
11
12
# config/initializers/apns.rb
# Default value is 'gateway.sandbox.push.apple.com'
APNS.host = "gateway.sandbox.push.apple.com"
# Path to your development.pem file
APNS.pem = File.join(Rails.root, "development.pem")
# if your iOS App is available on the App Store, Use the production.pem
# and change the host
if Rails.env.production?
APNS.host = "gateway.push.apple.com"
APNS.pem = File.join(Rails.root, "production.pem")
end

Passo 7: Enviando Push Notifications

Agora que temos nosso ambiente configurado para enviar Push Notifications, podemos enviá-las bem facilmente usando a gem APNS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class PostsController < ApplicationController
def create
post = Post.new(post_params)
# Get all devices stored on your database
# or filter based on your criteria
devices = Device.all
notifications = devices.map do |d|
APNS::Notification.new(d.token,
alert: post.title,
other: 'Here, you can pass custom info to your app')
end
APNS.send_notifications(notifications) if !notifications.empty?
end
protected
def post_params
params.require(:post).permit(:title, :content)
end
end

Ultimo Passo: Receber Push Notifications em nosso iOS App

Lembrando que precisamos usar um apple device, porque o iOS Simulator não suporta Push Notifications, precisamos apenas implementar um delegate na classe AppDelegate.swift

1
2
3
4
5
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
// Do whatever you want with this notification
// Ex: Reload data from server
NSLog("remote Notification: %@", userInfo)
}

Correr pro Abraço

Agora você poderá criar uma nova postagem em sua aplicação Rails que você receberá uma notificação. Lembrando que a Apple não garante a entrega de push notifications, ou seja, não dependa delas para ações criticas. A documentação da Apple é muito bem organizada. Vale a pena dar uma olhada.

Qualquer dúvida, comentários e críticas são bem vindas.