SDK

Customizations

In this page we'll dive deeper into several aspects of our iOS library that can be customized to match your needs.

Setting keys in code

Instead of relying on the Application Key and Application Secret in Notificare.plist, it is possible to set these in code while initializing:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    ...more code

    [[NotificarePushLib shared] initializeWithKey:@"xxx" andSecret:@"xxx"];
    [[NotificarePushLib shared] setDelegate:self];
    [[NotificarePushLib shared] launch];


    ...more code
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    ...more code

    NotificarePushLib.shared().initialize(withKey: "xxx", andSecret: "xxx")
    NotificarePushLib.shared().delegate = self
    NotificarePushLib.shared().launch()

    ...more code
}

These methods should be called before instantiating our library, in order to make sure the correct keys are used.

Library Options

The Notificare.plist is used by the library for setup and customization. It allows you to change the colours of the notifications' user interface or enable/disable certain functionality. By default we provide a colour scheme for some of our UI elements that might not match your app's look and feel and using the options below, you will be able to change that look & feel. Open you Notificare.plist and change the following properties if needed.

ios notificare plist 2 3

Localizable Texts

Our library ships with a default theme that can be customized if needed. Inside the DefaultTheme.bundle you will find several localized folders that contain all the texts used in the library. You are free to change those texts to match your needs and even add new languages if needed.

ios localizable texts

Using a Strings Dictionary for Rich Push Templates

In iOS 11, Apple extended hidden previews texts to all the apps. This will allow you to display a pre-defined text whenever a user chooses to hide the content of a notification preview in the lock screen or notification center. Include a Localizable.stringsdict file in your project, like the one below, in order to handle those texts correctly:

hidden previews ios strings dictionary

Please note that Notificare will have a default category for you that will apply to all your notifications so you must provide a text for the NotificareDefaultCategory and if you are using Rich Push Templates you should also create an entry for each template in your app.

In your Localizable.stringsdict file you should add the following entry for the default category and eventually several other entries that match your Rich Push Templates:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NotificareDefaultCategory</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@notification@</string>
        <key>notification</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>u</string>
            <key>zero</key>
            <string></string>
            <key>one</key>
            <string>%u notification</string>
            <key>two</key>
            <string></string>
            <key>few</key>
            <string></string>
            <key>many</key>
            <string></string>
            <key>other</key>
            <string>%u notifications</string>
        </dict>
    </dict>
    <key>MY_RICH_PUSH_TEMPLATE_TITLE</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@question@</string>
        <key>question</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>u</string>
            <key>zero</key>
            <string></string>
            <key>one</key>
            <string>%u message awaits your answer</string>
            <key>two</key>
            <string></string>
            <key>few</key>
            <string></string>
            <key>many</key>
            <string></string>
            <key>other</key>
            <string>%u messages awaits your answer</string>
        </dict>
    </dict>
</dict>
</plist>

If your app supports several languages, repeat the operation for every localization file. This will allow you to customize how your notifications show in the lock screen when Hidden Previews are enabled:

hidden previews ios

Non-Managed Implementation

Our library by default will override all the necessary App Delegate methods and manage it for you. You can (in case you using Swift you will need to) disable this behaviour by setting the DISABLE_APP_DELEGATE_PROXY property to YES in the Notificare.plist under the OPTIONS object. Once you disable it, you will need to implement additional App Delegate methods as described below:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [[NotificarePushLib shared] initializeWithKey:nil andSecret:nil];
    [[NotificarePushLib shared] setDelegate:self];
    [[NotificarePushLib shared] launch];
    [[NotificarePushLib shared] didFinishLaunchingWithOptions:launchOptions];
}

- (void)notificarePushLib:(NotificarePushLib *)library onReady:(nonnull NotificareApplication *)application {
    //If you want to register for remote notifications here it's safe to do it
    //You might want to consider calling this in response to a button in your on-boarding screen or some other place else
    [[NotificarePushLib shared] registerForNotifications];

}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
    [[NotificarePushLib shared]  handleOpenURL:url withOptions:options];
    // Handle Deep Links
    return YES;
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler{
    [[NotificarePushLib shared] continueUserActivity:userActivity restorationHandler:restorationHandler];
    return YES;
}

-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken {
    [[NotificarePushLib shared] didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler {
    [[NotificarePushLib shared] didReceiveRemoteNotification:userInfo completionHandler:^(id  _Nullable response, NSError * _Nullable error) {
        if (!error) {
            completionHandler(UIBackgroundFetchResultNewData);
        } else {
            completionHandler(UIBackgroundFetchResultNoData);
        }
    }];
}

-(void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(nonnull NSDictionary *)userInfo withResponseInfo:(nonnull NSDictionary *)responseInfo completionHandler:(nonnull void (^)())completionHandler{
    [[NotificarePushLib shared] handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:responseInfo completionHandler:^(id  _Nullable response, NSError * _Nullable error) {
        completionHandler();
    }];
}

-(void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(nonnull NSDictionary *)userInfo completionHandler:(nonnull void (^)())completionHandler{
    [[NotificarePushLib shared] handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:nil completionHandler:^(id  _Nullable response, NSError * _Nullable error) {
        completionHandler();
    }];
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
    NotificarePushLib.shared().initialize(withKey: nil, andSecret: nil)
    NotificarePushLib.shared().delegate = self
    NotificarePushLib.shared().launch()
    NotificarePushLib.shared().didFinishLaunching(withOptions: launchOptions)
}

func notificarePushLib(_ library: NotificarePushLib, onReady application: NotificareApplication) {
    NotificarePushLib.shared().registerForNotifications()
}

func application(_ application: UIApplication,
                 continue userActivity: NSUserActivity,
                 restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {

    NotificarePushLib.shared().continue(userActivity, restorationHandler: restorationHandler);
    return true
}

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    NotificarePushLib.shared().handleOpen(url, withOptions: options)
    // Handle Deep Links
    return true;
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    //If you want to register for remote notifications here it's safe to do it
    //You might want to consider calling this in response to a button in your on-boarding screen or some other place else
    NotificarePushLib.shared().didRegisterForRemoteNotifications(withDeviceToken: deviceToken)
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    NotificarePushLib.shared().didReceiveRemoteNotification(userInfo, completionHandler: {(_ response: Any?, _ error: Error?) -> Void in
        if error == nil {
            completionHandler(.newData)
        } else {
            completionHandler(.noData)
        }
    })
}

func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [AnyHashable : Any], withResponseInfo responseInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) {
    NotificarePushLib.shared().handleAction(withIdentifier: identifier, forRemoteNotification: userInfo, withResponseInfo: responseInfo, completionHandler: {(_ response: Any?, _ error: Error?) -> Void in
        completionHandler()
    })
}

func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) {
    NotificarePushLib.shared().handleAction(withIdentifier: identifier, forRemoteNotification: userInfo, withResponseInfo: nil, completionHandler: {(_ response: Any?, _ error: Error?) -> Void in
        completionHandler()
    })
}

After implementing these methods, make sure you also review the implementation guides located here.

Disable UNUserNotificationCenter delegate

Our library by default will assign itself as the delegate for the UNUserNotificationCenter automatically handling all the implementation for you. Starting with SDK 2.5.0, if you do want a different behaviour, you can disable it and implement it yourself in your app. This is done by setting the DISABLE_USER_NOTIFICATION_CENTER_DELEGATE property to YES in the Notificare.plist under the OPTIONS object. Once you disable it, you will need to implement the following methods:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [[NotificarePushLib shared] initializeWithKey:nil andSecret:nil];
    [[NotificarePushLib shared] setDelegate:self];
    [[NotificarePushLib shared] launch];

    UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter];
    [center setDelegate:self];

    ...more code
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
    [[NotificarePushLib shared] willPresentNotification:notification withCompletionHandler:^(UNNotificationPresentationOptions options) {
        completionHandler(options);
    }];
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
    [[NotificarePushLib shared] didReceiveNotificationResponse:response withCompletionHandler:^{
        completionHandler();
    }];
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {

    NotificarePushLib.shared().initialize(withKey: nil, andSecret: nil)
    NotificarePushLib.shared().delegate = self
    NotificarePushLib.shared().launch()

    if #available(iOS 10.0, *) {
        let center = UNUserNotificationCenter.current()
        center.delegate = self
    }

    ...more code
}

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    NotificarePushLib.shared().willPresent(notification) { (options) in
        completionHandler(options)
    }
}

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    NotificarePushLib.shared().didReceive(response) {
        completionHandler()
    }
}

This will effectively make sure you have total control over the UNUserNotificationCenter and you should then continue by reading the implementation guides located here.