To work with push notifications, create the HHFWPushNotifications application, which uses framework methods:
Method name | Brief description |
initWithCredentials (_: host: environment: project: device:) | The method initializes the framework. |
auth (_: password:) | The method authenticates the user by login and password. |
getTokens (handler:) | The method returns the list of tokens linked to server user. |
addToken (_: service: handler:) | The method sends token to server. |
removeTokens (_: handler:) | The method removes sent tokens from server. |
getTopics (handler:) | The method returns the message topics list. |
subscribeTopics (_: handler:) | The method subscribes to messages of the specified topic. |
unsubscribeTopics (_: handler:) | The method unsubscribes from messages of the specified topic. |
The HHFWPushNotifications application includes one screen, the UITextView text view, the UITextField text box and UIButton buttons:
Get tokens. Get a list of active tokens.
Add token. send token to a mobile platform server.
Remove token. Remove tokens from a mobile platform server.
Get topics. Get message topics list.
Subscribe. Subscribe to messages of the specified topic.
Unsubscribe. Unsubscribe from messages of the specified topic.
To execute the example:
Click the Get Tokens button.
Clicking the button initializes a request to get a tokens list for all devices added to get push notifications. The iOS devices list is empty.
Click the Add Token button.
Clicking the button adds the previously obtained device token to the tokens list on a mobile platform server.
Click the Get Tokens button to check if the token is added. The added token is displayed in the tokens list.
Click the Remove Token button.
Clicking the button removes the device token from the tokens list.
NOTE. If the device token is absent, the push notification service is not available for this device.
Add a device token again to the tokens list on a mobile platform server using the Add Token button.
Click the Get Tokens button to check if the token is added. The added token is displayed in the tokens list.
Click the Get Topics button.
Clicking the button returns all message topics that are available for subscription. The user is subscribed to the first message topic that is "subscribed = 1", and not subscribed to the second message topic that is "subscribed = 0".
Enter the topic2 message topic to the text box.
Click the Subscribe button.
Clicking the button subscribed to the topic2 message topic. A mobile platform server returns the response containing operation status.
Click the Get Topics button to check if the topic2 message topic is subscribed to. The current user is subscribed to the topic2 message topic that is "subscribed = 1".
Send a push notification to all users subscribed to the topic2 message topic. The message topic corresponds to the template2 template.
To send a push notification, execute a request:
$ 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"}'
After the request is executed, an notification is obtained with specified data in the request body:
Enter the topic2 message topic to the text box to unsubscribe.
Click the Unsubscribe button.
Clicking the button unsubscribes the user from getting messages of the topic2 topic. A mobile platform server returns the response containing operation status.
Click the Get Topics button to check unsubscription. The current user is not subscribed to the topic2 message topic that is "subscribed = 0".
Contents of the AppDelegate class:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Reset notifications counter after application start
UIApplication.shared.applicationIconBadgeNumber = 0
// Register sending of push notifications
self.registerForPushNotifications()
// Set up conditions for displaying push notifications
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) {
// Get mobile device token
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")
// Fix token in 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)
}
Application code:
import UIKit
class ViewController: UIViewController {
// Determine output variables
@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!
// Redetermine method
override func viewDidLoad() {
super.viewDidLoad()
self.deactivateButtons()
self.initializeFramework()
self.auth {
self.activateButtons()
self.resultTextView.text = "Authentication success"
}
}
// Set method that will be executed on button click
@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()
}
// Initialize framework
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
)
}
// Authenticate
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")
}
}
}
// Get mobile device token
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")
}
}
}
// Send token to a mobile platform server
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")
}
}
}
// Remove token from a mobile platform server
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")
}
}
}
// Get list of available message topics
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")
}
}
}
// Subscribe to receive messages with specific topic
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")
}
}
}
// Unsubscribe from receiving messages with specific topic
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")
}
}
}
// Set methods to display application user interface elements
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
}
}
See also: