GuidesDiscussions
Log In
Guides

iOS Integration

Steps for iOS Integration:

Step 1 : Navigate to the flutter project root folder in the terminal and run the commands.

flutter pub get
cd ios
pod deintegrate && pod install

Step 2: Open the project in Xcode.

  • Add Local Config file
  • Add Push Notifications capability to your target

  • Add Permissions:

Siprocal SDK needs few permissions which are listed below:

  • NSUserTrackingUsageDescription
  • UIBackgroundModes
    • Background fetch
    • Remote notifications

Add the following Background Modes:

Please add NSUserTrackingUsageDescription as a key to your original Info.plist file. Add the correct description for using the IDFA:


Step 3: Add App Groups.

Go to your app target and add a Capability called App Groups. Do the same for your Rich Notification target:



Add the following App Groups to:
a. Host Application's Info.plist
b. Rich Notification service extension's Info.plist

❗App Group Data

App Group's data should be same in both Host Application and Rich notification service extension.

<key>dbAppGroup</key>
<string>group.db.YOURAPPNAME.com</string>
<key>userDefaultsAppGroup</key>
<string>group.YOURAPPNAME.com</string>

Once added it would be similar to the image below


❗App Groups Naming

AppGroups string must be different for each host application otherwise there will be a shared database storage and shared user defaults storage between different apps.

Step 4: Create Notification Service Extension

To receive and display the Rich images in Push Notification, add the following code to NotificationService extending UNNotificationServiceExtension

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

@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];
    
    [DigitalReef includeMediaAttachmentWithRequest:request mutableContent:self.bestAttemptContent contentHandler:self.contentHandler];
}

- (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

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)
        DigitalReef.includeMediaAttachment(request: request, mutableContent: bestAttemptContent!, contentHandler: contentHandler)
    }
    
    override func 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.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}

Step 5: App Orientation (Optional)

Check the button at least once in order to add this key (UISupportedInterfaceOrientations) in the info.plist file or it can be added explicitly in the info.plist file by adding the key (UISupportedInterfaceOrientations) in the Info.plist file

<key>UISupportedInterfaceOrientations</key>
<array>
	<string>UIInterfaceOrientationLandscapeLeft</string>
	<string>UIInterfaceOrientationLandscapeRight</string>
	<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>


Step 6: Push Notification Permission

DR SDK needs to request Push Notification permission from the user to display the Ad Notifications. Below is the sample code to invoke the same from any View Controller class.

_siprocalPlugin.requestPushPermission();

Push Notifications (Optional)

In case you have another push SDK or an implementation of your own, you might want to turn off Siprocal SDK's method swizzling. Siprocal SDK performs method swizzling on top of iOS' APNS delegate methods to capture relevant events from notifications and analytics. This means that when our SDK is present, it overrides whatever other APNS implementation already present in the app.

Firebase Messaging

If you already have FCM Integration into your project, you need to create the methods for firebase:

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.

Disable Method Swizzling:

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

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

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