Пример работы с push-уведомлениями

Для работы с push-уведомлениями создайте приложение «HHFWPushNotifications», в котором используются методы фреймворка:

Имя метода Краткое описание
initWithCredentials (_: host: environment: project: device:) Метод выполняет инициализацию фреймворка.
auth (_: password:) Метод выполняет аутентификацию пользователя по логину и паролю.
getTokens (handler:) Метод возвращает список токенов, привязанных к пользователю на сервере.
addToken (_: service: handler:) Метод отправляет токен на сервер.
removeTokens (_: handler:) Метод удаляет переданные токены с сервера.
getTopics (handler:) Метод возвращает список тем сообщений.
subscribeTopics (_: handler:) Метод осуществляет подписку на сообщения определенной темы.
unsubscribeTopics (_: handler:) Метод осуществляет отписку от сообщений определенной темы.

Приложение «HHFWPushNotifications» состоит из одного экрана, текстового представления «UITextView», текстового поля «UITextField» и кнопок «UIButton»:

Для выполнения примера:

  1. Нажмите кнопку «Get tokens».

При нажатии на кнопку инициализируется запрос списка токенов всех устройств, которые были добавлены для получения push-уведомлений. Список устройств iOS пуст.

  1. Нажмите кнопку «Add token».

При нажатии на кнопку добавится заранее полученный токен устройства в список токенов на сервере мобильной платформы.

  1. Нажмите кнопку «Get tokens» для проверки добавления токена. В списке токенов содержится добавленный токен.

  1. Нажмите кнопку «Remove token».

При нажатии на кнопку токен устройства удаляется из списка токенов.

Примечание. При отсутствии токена устройства сервис push-уведомлений будет недоступен для данного устройства.

  1. Добавьте заново токен устройства в список токенов на сервере мобильной платформы с помощью кнопки «Add token».

  2. Нажмите кнопку «Get tokens» для проверки добавления токена. В списке токенов содержится добавленный токен.

  1. Нажмите кнопку «Get topics».

При нажатии на кнопку возвращаются все темы сообщений, которые доступны к подписке. Пользователь подписан на первую тему сообщений - «subscribed = 1», на вторую тему сообщений нет подписки - «subscribed = 0».

  1. Введите в текстовое поле тему сообщений «topic2».

  2. Нажмите кнопку «Subscribe».

При нажатии на кнопку выполнится подписка на тему сообщений «topic2». Сервер мобильной платформы вернет ответ с указанием статуса операции.

  1. Нажмите кнопку «Get topics» для проверки подписки на тему сообщений «topic2». Текущий пользователь подписан на тему сообщений «topic2» - «subscribed = 1».

  1. Отправьте push-уведомление всем пользователям, подписанным на тему сообщений «topic2». Тема сообщений соответствует шаблону «template2».

Для отправки push-уведомления выполните запрос:

    $ curl -X POST  <host>/api/v1/push/send/template2/topic/topic2/
        -H 'Authorization: Bearer <token>’  
        -H 'Content-Type: application/json'  
        -d '{"title": "Game Request", "body": "Bob wants to play poker"}'

После выполнения запроса будет получено уведомление с указанными данными в теле запроса:

  1. Введите в текстовое поле тему сообщений «topic2» для отписки.

  2. Нажмите кнопку «Unsubscribe».

При нажатии на кнопку пользователь будет отписан от получения сообщений темы «topic2». Сервер мобильной платформы вернет ответ с указанием статуса операции.

  1. Нажмите кнопку «Get topics» для проверки отписки. Текущий пользователь не подписан на тему сообщений «topic2» - «subscribed = 0».

Содержимое класса AppDelegate:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
 
    // Сбросим счетчик уведомлений после запуска приложения
    UIApplication.shared.applicationIconBadgeNumber = 0
 
    // Зарегистрируем отправку push-уведомлений
    self.registerForPushNotifications()
 
    // Настроим условия отображения push-уведомлений
    if let notification = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] as? [String: AnyObject] {
        print(notification)
    }
    return true
}
 
func registerForPushNotifications() {
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
        print("Permission granted: \(granted)")
        guard granted else { return }
        self.getNotificationSettings()
    }
}
 
func getNotificationSettings() {
    UNUserNotificationCenter.current().getNotificationSettings { (settings) in
        print("Notification settings: \(settings)")
        guard settings.authorizationStatus == .authorized else { return }
        DispatchQueue.main.async {
            UIApplication.shared.registerForRemoteNotifications()
        }
    }
}
 
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
 
    // Получим токен мобильного устройства
    let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
    let token = tokenParts.joined()
    print("Device Token: \(token)")
 
    // Зафиксируем токен в UserDefaults
    UserDefaults.standard.set(token, forKey: "TokenUserDefaultsKey")
}
 
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print("Failed to register: \(error)")
}
 
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    let aps = userInfo["aps"] as! [String: AnyObject]
    print(aps)
}

Код приложения:

import UIKit
 
class ViewController: UIViewController {
 
    // Определим выходные переменные
    @IBOutlet weak var topicTextField: UITextField!
    @IBOutlet weak var resultTextView: UITextView!
    @IBOutlet weak var getTokensButton: UIButton!
    @IBOutlet weak var addTokenButton: UIButton!
    @IBOutlet weak var removeTokensButton: UIButton!
    @IBOutlet weak var getTopicsButton: UIButton!
    @IBOutlet weak var subscribeButton: UIButton!
    @IBOutlet weak var unsubscribeButton: UIButton!
 
    // Переопределим метод
    override func viewDidLoad() {
        super.viewDidLoad()
        self.deactivateButtons()
        self.initializeFramework()
        self.auth {
            self.activateButtons()
            self.resultTextView.text = "Authentication success"
        }
    }
 
    // Зададим метод, который будет выполняться при нажатии на кнопку
    @IBAction func getTokensPressed() {
        self.getTokens { (jsonResult) in
            self.resultTextView.text = String(format: "%@", jsonResult)
        }
    }
 
    @IBAction func addTokenPressed() {
        self.addToken { (jsonResult) in
            self.resultTextView.text = String(format: "%@", jsonResult)
        }
    }
 
    @IBAction func removeTokensPressed() {
        self.removeToken { (jsonResult) in
            self.resultTextView.text = String(format: "%@", jsonResult)
        }
    }
 
    @IBAction func getTopicsPressed() {
        self.getTopics { (jsonResult) in
            self.resultTextView.text = String(format: "%@", jsonResult)
        }
    }
 
    @IBAction func subscribePressed() {
        self.subscribe { (jsonResult) in
            self.resultTextView.text = String(format: "%@", jsonResult)
        }
    }
 
    @IBAction func unsubscribePressed() {
        self.unsubscribe { (jsonResult) in
            self.resultTextView.text = String(format: "%@", jsonResult)
        }
    }
 
    @IBAction func viewTapped(_ sender: UITapGestureRecognizer) {
        self.topicTextField.resignFirstResponder()
    }
 
    // Выполним инициализацию фреймворка
    private func initializeFramework() {
        let apiVersion: String = "v1"
        let host: String = "http://testmasterfmp.fsight.cloud/"
        let environment: String = "Leonid_environment"
        let project: String = "Leonid_project"
        let device: String = (UIDevice.current.identifierForVendor?.uuidString)!
        HHFWController.sharedInstance().initWithCredentials(
            apiVersion,
            host: host,
            environment: environment,
            project: project,
            device: device
        )
    }
 
    // Выполним аутентификацию
    private func auth(completion: @escaping ()->()) {
        let username: String = "Leonid"
        let password: String = "123123"
        HHFWController.sharedInstance().auth(username, password: password){ (jsonResult) in
            if let jsonDict = jsonResult as? NSDictionary,
                let status = jsonDict["status"] as? String, status == "ok" {
                print("Auth success")
                completion()
            } else {
                print("Auth error")
            }
        }
    }
 
    // Получим токен мобильного устройства
    private func getTokens(completion: @escaping (NSDictionary)->()) {
        HHFWController.sharedInstance().getTokens { (jsonResult) in
            if let jsonDict = jsonResult as? NSDictionary,
                let status = jsonDict["status"] as? String, status == "ok" {
                print("Get tokens success")
                completion(jsonDict)
            } else {
                print("Get tokens error")
            }
        }
    }
 
    // Отправим токен на сервер мобильной платформы
    private func addToken(completion: @escaping (NSDictionary)->()) {
        guard let token = UserDefaults.standard.string(forKey: "TokenUserDefaultsKey") else { return }
        let service: String = "apns"
        HHFWController.sharedInstance().addToken(token, service: service) { (jsonResult) in
            if let jsonDict = jsonResult as? NSDictionary,
                let status = jsonDict["status"] as? String, status == "ok" {
                print("Add token success")
                completion(jsonDict)
            } else {
                print("Add token error")
            }
        }
    }
 
    // Удалим токен с сервера мобильной платформы
    private func removeToken(completion: @escaping (NSDictionary)->()) {
        guard let token = UserDefaults.standard.string(forKey: "TokenUserDefaultsKey") else { return }
        HHFWController.sharedInstance().removeTokens([token]) { (jsonResult) in
            if let jsonDict = jsonResult as? NSDictionary,
                let status = jsonDict["status"] as? String, status == "ok" {
                print("Remove tokens success")
                completion(jsonDict)
            } else {
                print("Remove tokens error")
            }
        }
    }
 
    // Получим список доступных тем сообщений
    private func getTopics(completion: @escaping (NSDictionary)->()) {
        HHFWController.sharedInstance().getTopics { (jsonResult) in
            if let jsonDict = jsonResult as? NSDictionary,
                let status = jsonDict["status"] as? String, status == "ok" {
                print("Get topics success")
                completion(jsonDict)
            } else {
                print("Get topics error")
            }
        }
    }
 
    // Подпишемся на получение сообщений определенной темы
    private func subscribe(completion: @escaping (NSDictionary)->()) {
        guard let topic = self.topicTextField.text else { return }
        HHFWController.sharedInstance().subscribeTopics([topic]) { (jsonResult) in
            if let jsonDict = jsonResult as? NSDictionary,
                let status = jsonDict["status"] as? String, status == "ok" {
                print("Subscribe topics success")
                completion(jsonDict)
            } else {
                print("Subscribe topics error")
            }
        }
    }
 
    // Отпишемся от получения сообщений определенной темы
    private func unsubscribe(completion: @escaping (NSDictionary)->()) {
        guard let topic = self.topicTextField.text else { return }
        HHFWController.sharedInstance().unsubscribeTopics([topic]) { (jsonResult) in
            if let jsonDict = jsonResult as? NSDictionary,
                let status = jsonDict["status"] as? String, status == "ok" {
                print("Unsubscribe topics success")
                completion(jsonDict)
            } else {
                print("Unsubscribe topics error")
            }
        }
    }
 
    // Зададим методы для отображения элементов пользовательского интерфейса приложения
    private func deactivateButtons() {
        self.getTokensButton.isEnabled = false
        self.addTokenButton.isEnabled = false
        self.removeTokensButton.isEnabled = false
        self.getTopicsButton.isEnabled = false
        self.subscribeButton.isEnabled = false
        self.unsubscribeButton.isEnabled = false
    }
 
    private func activateButtons() {
        self.getTokensButton.isEnabled = true
        self.addTokenButton.isEnabled = true
        self.removeTokensButton.isEnabled = true
        self.getTopicsButton.isEnabled = true
        self.subscribeButton.isEnabled = true
        self.unsubscribeButton.isEnabled = true
    }
}

См. также:

Примеры использования iOS-фреймворка