Interactive Push Notifications 🤔

Ahmet Keskin
Dolap Tech
Published in
4 min readNov 25, 2017

Hey Everyone,

I am gonna try to explain how we do interactive push notification in dolap.com. First of all, we are working with great backend developers in dolap.com and as an iOS developer i’m getting advantage of this.

One of the great moment in our journey is that me and Yiğit Darçın’s discussions about interactive push notification. By the way he is our lead and co-founder 👊.

Let see what we will talk about in this post;

  • How do we set notification category and its actions
  • How do we handle actions.

Notification Category And Actions

The first thing about adding UNNotificationCategory & UNNotificationAction is that every thing will be static and we will add what we need. That was the first thing that came to mind. For example if we need like action on some random product push notification, we will add like category and its action. Or we want users can bid easily with push action for a product, we will add bid category and its actions right? But that was the easy and not a visionary way. We need more stable and reusable way.

After this intro we discussed how we implement interactive push and decided to make categories and their actions registration dynamically. So our implementation should be api based

Lets see some code;

class PushNotificationCategory: Mappable {
var name : String?
var pushActions : [PushNotificationAction]?

required init?(map: Map) {
}
func mapping(map: Map) {
name <- map[“name”]
pushActions <- map[“pushActions”]
}
}
class PushNotificationAction: Mappable {
var identifier : String?
var buttonTitle : String?
required init?(map: Map) {} func mapping(map: Map) {
identifier <- map["identifier"]
buttonTitle <- map["buttonTitle"]
}
}

These are our model class for fetching and mapping data. After data fetch we need to register our categories and their actions.

func registerPushNotificationCategories(categories : [PushNotificationCategoryDTO]?) {guard let categories = categories else {
if #available(iOS 10.0, *) {
let notificationCategories = Set<UNNotificationCategory>()
UNUserNotificationCenter.current().setNotificationCategories(notificationCategories)
} else {
// Fallback on earlier versions
}
return }
if #available(iOS 10.0, *) {
var notificationCategories = Set<UNNotificationCategory>()
for category in categories {
var actionList = [UNNotificationAction]()
for action in category.pushActions! {
let action = UNNotificationAction(identifier: action.identifier!, title: action.buttonTitle!, options: [])
actionList.append(action)
}
let category = UNNotificationCategory(identifier: category.name!, actions: actionList, intentIdentifiers: [], options: [])
notificationCategories.insert(category)
}
UNUserNotificationCenter.current().setNotificationCategories(notificationCategories)
} else {}}

Check the categories is empty or not. If its empty register empty category list.

let notificationCategories = Set<UNNotificationCategory>()
UNUserNotificationCenter.current().setNotificationCategories(notificationCategories)

If the categories which we fetched from server is not empty, we will create notification categories and their actions.

var notificationCategories = Set<UNNotificationCategory>()
for category in categories {
var actionList = [UNNotificationAction]()
for action in category.pushActions! {
let action = UNNotificationAction(identifier: action.identifier!, title: action.buttonTitle!, options: [])
actionList.append(action)
}
let category = UNNotificationCategory(identifier: category.name!, actions: actionList, intentIdentifiers: [], options: [])
notificationCategories.insert(category)
}
UNUserNotificationCenter.current().setNotificationCategories(notificationCategories)

How do we handle actions?

Well we registered categories. What about actions? We can not determine static actions because we want everything should be dynamic. Actions will do network request no second thought about it.

And api base implementation comes at this point. What will we have when a push notification received?

  • categoryIdentifier
  • actionIdentifier

We will use category and action identifiers for detecting notification type and its action.

class PushActionRequest: NSObject {
var action : String?
var category : String?
var payload : String?

override init() {}
func getParameters() -> Dictionary<String,AnyObject>{
var parameters = Dictionary<String,AnyObject>()
parameters["action"] = self.action as AnyObject
parameters["category"] = self.category as AnyObject?
parameters["payload"] = self.payload as AnyObject?
return parameters
}
}

Well this is our push action request object. We will use this object for notification actions api request. But there is one more data which is payload. Why do we have payload and what does it work?

Why do we have payload?

We want that everything should be dynamic and api based. So client does not need to know anything. We will receive payload in push notification and pass it back to the server with request.

What does it work?

I’ll explain it with examples. For instance you want to send like request, you need at least product id. Or you want to follow a member, you definitely need to know member id right? That is the place where payload shines. Api send you payload in userInfo and you send it to api back. So again client does not need to know anything 😉

Finally make your logic in userNotificationCenter didReceive method and enjoy the rest 👊

You have userInfo, categoryIdentifier, actionIdentifier and more..

Well thats it, i hope you enjoyed the post 🙌 👋

--

--