GuidesDiscussions
Log In
Guides

Push Notifications

Disable Method Swizzling

By adding the Boolean key DigitalReefSwizzlingEnabled with value NO to your Info.plist file you will be disabling DR SDK's method swizzling:

<key>DigitalReefSwizzlingEnabled</key>
<false/>

🚧

Firebase Messaging

If you have Firebase Messaging on your project, we recommend that you also disable method swizzling on Firebase side by adding FirebaseAppDelegateProxyEnabled as NO in your Info.plist. More information on link.

Add APNS methods to your AppDelegate

When method swizzling is disabled, you need to add the APNS delegate methods and call DR SDK on specific places

Changes for AppDelegate.h file

#import <UIKit/UIKit.h>
#import <UserNotifications/UNUserNotificationCenter.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>
@end

Changes for AppDelegate.m file

import UIKit
import DigitalReefSDK

@main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    var window: UIWindow?
    
    var digitalReef: DigitalReef = DigitalReef.shared

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        UNUserNotificationCenter.current().delegate = self
        application.registerForRemoteNotifications()
        return true
    }
    
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        let drAd: Bool = userInfo["adAvailable"] as? Bool ?? false
        if(drAd){
            print("DR SDK")
            DigitalReef.shared.didReceiveRemoteNotification(application: application, userInfo: userInfo, fetchCompletionHandler: completionHandler)
        }else{
            print("Other SDK")
        }
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        DigitalReef.shared.didRegisterForRemoteNotificationsWithDeviceToken(application, deviceToken: deviceToken)
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        let drAd: Bool = userInfo["adAvailable"] as? Bool ?? false
        if(drAd){
            print("DR SDK")
            DigitalReef.shared.didReceiveNotificationResponse(center: center, didReceive: response, withCompletionHandler: completionHandler)
        }else{
            print("Other SDK")
        }
    }
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        let userInfo = notification.request.content.userInfo
        let drAd: Bool = userInfo["adAvailable"] as? Bool ?? false
        if(drAd){
            print("DR SDK")
            DigitalReef.shared.willPresentNotification(center: center, willPresent: notification, withCompletionHandler: completionHandler)
        }else{
            print("Other SDK")
        }
    }
}
Add below code in NotificationServiceExtension file

import UserNotifications
import DigitalReefSDK

class NotificationService: UNNotificationServiceExtension {
    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?
    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        
        let userInfo = request.content.userInfo
        let drAd: Bool = userInfo["adAvailable"] as? Bool ?? false
        if(drAd){
            print("DR SDK")
            DigitalReef.includeMediaAttachment(request: request, mutableContent: bestAttemptContent!, contentHandler: contentHandler)
        }else{
            print("Other SDK")
        }
    }
    
    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}



#import "AppDelegate.h"
#import <DigitalReefSDK/DigitalReefSDK.h>

@interface AppDelegate ()
@property (nonatomic, strong) DigitalReef *digitalReef;
@end

@implementation AppDelegate
- (instancetype)init{
    self = [super init];
    if(self){
        self.digitalReef = DigitalReef.shared;
    }
    return self;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //Need to set this delegate, when DigitalReefSwizzlingEnabled bool is set false in info.plist file
    [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
    [application registerForRemoteNotifications];
    return YES;
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
    BOOL drAd = userInfo[@"adAvailable"];
    if(drAd == YES){
        NSLog(@"DR SDK");
        [self.digitalReef didReceiveRemoteNotificationWithApplication:application userInfo:userInfo fetchCompletionHandler:completionHandler];
    }else{
        NSLog(@"Other SDK");
    }
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    [self.digitalReef didRegisterForRemoteNotificationsWithDeviceToken:application deviceToken:deviceToken];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
    BOOL drAd = notification.request.content.userInfo[@"adAvailable"];
    if(drAd == YES){
        NSLog(@"DR SDK");
        [self.digitalReef willPresentNotificationWithCenter:center willPresent:notification withCompletionHandler:completionHandler];
    }else{
        NSLog(@"Other SDK");
    }
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
    BOOL drAd = response.notification.request.content.userInfo[@"adAvailable"];
    if(drAd == YES){
        NSLog(@"DR SDK");
        [self.digitalReef didReceiveNotificationResponseWithCenter:center didReceive:response withCompletionHandler:completionHandler];
    }else{
        NSLog(@"Other SDK");
    }
    
}
@end

Add this in NotificationService.m file

#import "NotificationService.h"
@import DigitalReefSDK;
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@end
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    BOOL drAd = request.content.userInfo[@"adAvailable"];
    if(drAd == YES){
        NSLog(@"DR SDK");
        [DigitalReef includeMediaAttachmentWithRequest:request mutableContent:self.bestAttemptContent contentHandler:self.contentHandler];
    }else{
        NSLog(@"Other SDK");
    }
}
- (void)serviceExtensionTimeWillExpire {
    // Called just before the extension will be terminated by the system.
    // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
    self.contentHandler(self.bestAttemptContent);
}
@end

Notification Center Feature (Optional)

As a Host App developer if you prefer to show the Notification for Ads in your App's Notification Center, you can utilise the features listed below.

This section is completely optional.

Functions exposed are as follows:

  • func addOTAObserver(_ otaObserver: OTAObserver)
  • func removeOTAObserver(_ otaObserver: OTAObserver)
  • func notifySDKForOTAEventPerformedInHostApp(otaPromotionId: String, otaEvent: OTAEvent)

Implementation Steps:

  1. Add the Observer at any class or at Appdelegate in order to observe any changes made on the OTAPromotion objects.
  2. Remove the Observer at the same class or at Appdelegate when that class is no longer in use/required to observe any changes made on the OTAPromotion objects.
  3. Notify DR SDK whenever some action is performed on any of the OTAPromotion that was received in the Host Application.

Example:

AppDelegate class will observe changes made on the OTAPromotion objects.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Step 1   
    DigitalReef.shared.addOTAObserver(self)

    //....

    return true
}

func applicationWillTerminate(_ application: UIApplication) {
    // Step 2
	  DigitalReef.shared.removeOTAObserver(self)
}

//Observe changes 
extension AppDelegate : OTAObserver {
    func received(otaPromotion: DigitalReefSDK.OTAPromotion) {
        //Handle the OTAPromotion object in the Host app.
    }
    func receivedAction(otaPromotionId: String, otaEvent: DigitalReefSDK.OTAEvent) {
        //Handle the action performed received on OTAPromotion object.
    }
}

// Step 3
DigitalReef.shared.notifySDKForOTAEventPerformedInHostApp(otaPromotionId: String, otaEvent: OTAEvent)

//------------AppDelegate.h--------------//
#import <UIKit/UIKit.h>
#import <UserNotifications/UNUserNotificationCenter.h>
#import <DigitalReefSDK/DigitalReefSDK.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate, OTAObserver>
@end
//------------AppDelegate.h--------------//
  
//------------AppDelegate.m--------------//
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Step 1
    [DigitalReef.shared addOTAObserver:self];
    return YES;
}

- (void)applicationWillTerminate:(UIApplication *)application{
     // Step 2
     [DigitalReef.shared removeOTAObserver:self];
}

//Observe changes
- (void)receivedActionWithOtaPromotionId:(NSString * _Nonnull)otaPromotionId otaEvent:(enum OTAEvent)otaEvent { 
    //Handle the action performed received on OTAPromotion object.
}
- (void)receivedWithOtaPromotion:(OTAPromotion * _Nonnull)otaPromotion { 
    //Handle the OTAPromotion object in the Host app.
}

//------------AppDelegate.m--------------//

// Step 3
[DigitalReef.shared notifySDKForOTAEventPerformedInHostAppWithOtaPromotionId:(NSString * _Nonnull) otaEvent:(enum OTAEvent)];

Object for Reference

protocol OTAObserver {
    func received(otaPromotion: OTAPromotion)
    func receivedAction(otaPromotionId: String, otaEvent: OTAEvent)
}

enum OTAEvent: Int {
    case VIEWED = 1
    case CLICK = 2
    case CLOSED_NOTIFICATION = 3
    case ERROR = 4
}

class OTAPromotion : NSObject, Codable {
    public var id: String
    public var actionUrl: String
    public var actionType: String
    public var category: String
    public var actionId: String
    public var otaNotification: OtaNotification
    public var createdAt: Int
    public var startedAt: Int
    public var finalizedAt: Int
    
    init(id: String, actionUrl: String, actionType: String, category: String, actionId: String, otaNotification: OtaNotification, createdAt: Int, startedAt: Int, finalizedAt: Int) {
        self.id = id
        self.actionUrl = actionUrl
        self.actionType = actionType
        self.category = category
        self.actionId = actionId
        self.otaNotification = otaNotification
        self.createdAt = createdAt
        self.startedAt = startedAt
        self.finalizedAt = finalizedAt
    }
}

class OtaNotification : NSObject, Codable{
    public var contentTitle: String
    public var contentText: String
    public var expandedIcon: String
    public var icon: String
    public var bigImage: String
    
    init(contentTitle: String, contentText: String, expandedIcon: String, icon: String, bigImage: String) {
        self.contentTitle = contentTitle
        self.contentText = contentText
        self.expandedIcon = expandedIcon
        self.icon = icon
        self.bigImage = bigImage
    }
}