Using Custom Data

Customize your messages with custom data passed in the push payload

This guide will help you to better understand how to pass custom data to your apps in the push notification payload so your app could react to such pushes and perform various actions accordingly.

The ways you handle custom data can vary according to your business objectives. In this article we’ll show some basic examples of parsing custom data and performing simple actions:

  • Opening CustomPageViewController and changing the backgound color

  • A/B testing using custom data

  • Changing App Icon

Prerequisites

This guide covers iOS Native development. It is assumed that you have iOS sample application configured and receiving push notifications as per iOS Getting Started guide.

In AppDelegate in didFinishLaunchingWithOptions function we will use self.viewController as a delegate for push notifications processing:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
   Pushwoosh.sharedInstance().delegate = self.viewController
   Pushwoosh.sharedInstance().registerForPushNotifications()
        
   if let launchOptions = launchOptions {
       Pushwoosh.sharedInstance().handlePushReceived(launchOptions)
   }
   return true
}

Our ViewController implements the PWMessagingDelegate protocol:

extension ViewController: PWMessagingDelegate

And therefore has onMessageOpened function that handles received push notifications:

// User pressed on the push notification
func pushwoosh(_ pushwoosh: Pushwoosh, onMessageOpened message: PWMessage) {}

Opening another ViewController and changing the background color

Now we are getting customData from the push payload. For instance, let's change the view's background color and discount percentage. We assume that the custom data will contain the items “r”, “g”, “b”, and "d" in JSON object format as follows:

guard let customDataJson = message.customData,
              let redString = customDataJson["r"] as? String,
              let greenString = customDataJson["g"] as? String,
              let blueString = customDataJson["b"] as? String,
              let discount = customDataJson["d"] as? String else {
            return
            }
setViewBackgroundColor(red: redString, green: greenString, blue: blueString, discount: discount) 

We will use the following function to open a new ViewController and set the background color and discount percentage:

    func setViewBackgroundColor(red: String, green: String, blue: String, discount: String) {
        let red = CGFloat((red as NSString).floatValue)
        let green = CGFloat((green as NSString).floatValue)
        let blue = CGFloat((blue as NSString).floatValue)
        
        let color = UIColor(red: red / 255.0, green: green / 255.0, blue: blue / 255.0, alpha: 1)

        if let topController = UIApplication.shared.topMostController() {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            if let customViewController = storyboard.instantiateViewController(withIdentifier: "custom_page") as? CustomPageViewController {
                customViewController.discount = discount
                customViewController.bgColor = color
                topController.present(customViewController, animated: true, completion: nil)
            }
        }
    }

Let’s test our example. Navigate to Pushwoosh Journey and add a Push element to the canvas. Next, click on Create new content. In the Push content form that opens, enter any push notification text.

Then toggle Send custom data on. Insert the JSON into the Custom data field.

As we've decided that our custom data format would be JSON object with “r”, “g”, “b” values in it, we need to use “custom data” field in the Control Panel and populate it with JSON object {"r":"30", "g":"144", "b":"255", "d":"25"}:

Upon tapping the push notification, the CustomPageViewController opens, the background color is set, and the discount is applied:

CustomPageViewController code:

class CustomPageViewController: UIViewController {
    
    var bgColor: UIColor?
    var discount: String?

    @IBOutlet weak var titleLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = self.bgColor
        
        if self.discount != nil {
            self.titleLabel?.text = "ONLY TODAY GET \(self.discount!)% DISCOUNT!"
        }
    }
    
    func showPromoPage(discount: String) {
        let vc = CustomPageViewController()
        vc.bgColor = self.view.backgroundColor
        vc.discount = discount
        vc.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
        
        if self.presentedViewController != nil {
            self.dismiss(animated: true, completion: {
                self.present(vc, animated: true, completion: nil)
            })
        } else {
            self.present(vc, animated: true, completion: nil)
        }
    }

    @IBAction func closeButtonAction(_ sender: Any) {
        self.dismiss(animated: true)
    }
}

We assume that the discount value will come as "d" parameter in JSON of the push notifications payload. As push notification payload is limited in size you’d rather use short names for the parameters.

guard let customDataJson = message.customData,
              let redString = customDataJson["r"] as? String,
              let greenString = customDataJson["g"] as? String,
              let blueString = customDataJson["b"] as? String,
              let discount = customDataJson["d"] as? String else {
            return
        }

You can write code to initialize and open different View Controllers depending on the parameters you pass in push notifications payload.

Opening A/B Testing View Controller

Let's consider another use case for custom data in a push notification. For instance, we need to open one view controller for one user segment and another view controller for a different user segment. Simply put, we can use custom data for A/B testing in your application.

Let's create two view controllers. One controller (A) will open with a discount value, and the second controller (B) will open with a different discount parameter.

Now let's write the code that will open the appropriate view controller based on the push notification payload:

func pushwoosh(_ pushwoosh: Pushwoosh, onMessageOpened message: PWMessage) {
    // MARK: - A/B Testing via Custom Data
    guard let customDataJson = message.customData,
          let viewController = customDataJson["vc"] as? String else {
        return
    }
        
    if viewController == a {
        setControllerA()
    } else if viewController == b {
        setControllerB()
    }
}

    func setControllerA() {
        if let topController = UIApplication.shared.topMostController() {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            if let customViewController = storyboard.instantiateViewController(withIdentifier: "a_vc") as? AViewController {
                customViewController.discountA = "50"
                topController.present(customViewController, animated: true, completion: nil)
            }
        }
    }
    
    func setControllerB() {
        if let topController = UIApplication.shared.topMostController() {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            if let customViewController = storyboard.instantiateViewController(withIdentifier: "b_vc") as? BViewController {
                customViewController.discountB = "100"
                topController.present(customViewController, animated: true, completion: nil)
            }
        }
    }

Depending on the custom data you sent in the push payload, either 'vc': 'A' or 'vc': 'B', one segment of users will open one controller, while another segment of users will open a different controller.

That's it!

Changing app icon via push notification

Another example of how we can use push notifications in iOS to change the app icon.

First, let's add three different icons to the assets. One will be used as the default app icon, while the other two will change based on the custom data in the push notification.

To enable alternate app icons in your iOS application, you need to add the necessary configuration in the Info.plist file. Here are the steps to do that:

	<key>CFBundleIcons</key>
	<dict>
		<key>CFBundleAlternateIcons</key>
		<dict>
			<key>AppIcon-2</key>
			<dict>
				<key>CFBundleIconFiles</key>
				<array>
					<string>Icon-2</string>
				</array>
				<key>UIPrerenderedIcon</key>
				<true/>
			</dict>
			<key>AppIcon-3</key>
			<dict>
				<key>CFBundleIconFiles</key>
				<array>
					<string>Icon-3</string>
				</array>
				<key>UIPrerenderedIcon</key>
				<true/>
			</dict>
		</dict>
		<key>CFBundlePrimaryIcon</key>
		<dict>
			<key>CFBundleIconFiles</key>
			<array>
				<string>Icon-1</string>
			</array>
			<key>UIPrerenderedIcon</key>
			<true/>
		</dict>
	</dict>

In the pushwoosh(_ pushwoosh: Pushwoosh,onMessageOpened message: PWMessage) callback, you can add the code to change the app icon based on the custom data received in the push notification. Here’s how you can implement this:

    func pushwoosh(_ pushwoosh: Pushwoosh, onMessageOpened message: PWMessage) {
        // MARK: - Change the app icon dynamically
        guard let customDataJson = message.customData,
              let appIcon = customDataJson["i"] as? String else {
                  return
              }
        
        UIApplication.shared.setAlternateIconName(appIcon) { error in
            if let error = error {
                print(error.localizedDescription)
            } else {
                print("Success!")
            }
        }
    }

When tapping on the push notification, the system will prompt you to change the app icon on the device.

Done!

You can find the project utilizing custom data on GitHub.

Last updated