What you will learn

Herow allows you to manage several notification options, such as the maximum number of notifications the SDK can display over a given period of time, or the minimum time span between two notifications.

Depending on your objectives with zones, you may want to add specific filters to refine the exact conditions around notification display in your app – for instance, to match notifications with specific user profiles, or to enable users to activate/deactivate specific types of notifications based on their personal preferences.

This is what we call Custom Notification Filters. This tutorial will guide through their creation & registration process with our SDK, and give you simple, practical illustrations to start working with them.

Pre-requisites - What you need to get started

Step 1: Clone the sdk-tutorial repository

  • Clone the sdk-tutorial repository
git clone https://github.com/Connecthings/sdk-tutorial.git

objectivec

  • Open the ios>ObjectiveC>Zone>2-Notification>Starter folder

SWIFT

  • Open the ios>SWIFT>Zone>2-Notification>Starter folder

Step 2: Configure the SDK

  • Configure your CocoaPod files and .plist
  • Configure your SDK with:
    • the appropriate Herow Environment ( PREPROD / PROD )
    • your SDK credentials

Switch to Swift

[[[[HerowInitializer sharedInstance] configPlatform: HerowPlatform.prod]
									 configUserWithLogin:@"your username"
									 password:@"your password"
									 company:@"your company"]
									 synchronize];

herowInitializer = HerowInitializer.shared
herowInitializer?.configPlatform(Platform.prod)
				 .configUser(login: "your username", password: "your password", company: "your company")
				 .synchronize()

If you need more informations, have a look to the 5 minutes quickstart tutorial

Step 3: Create a Notification Filter

  • Create a MyNotificationFilter class in the project
  • Open the MyNotificationFilter file
  • Import the ConnectPlaceActions package

Switch to Swift

@import ConnectPlaceActions;
import ConnectPlaceActions
  • The MyNotificationFilter file must implement the NotificationFilter delegate

Switch to Swift

@interface MyNotificationFilter: NSObject <NotificationFilter>

@end

class MyNotificationFilter: NotificationFilter {
  • Open the MyNotificationFilter file
  • Implement the methods of the NotificationFilter

Switch to Swift

@implementation MyNotificationFilter

- (NSString * _Nonnull)getName {
    return @"";
}

- (BOOL)createNewNotificationWithPlaceNotification:(id<PlaceNotification> _Nonnull)placeNotification {
    return false;
}

- (BOOL)deleteCurrentNotificationWithPlaceNotification:(id<PlaceNotification>)placeNotification {
    return false;
}

- (void)loadWithUserDefaults:(NSUserDefaults * _Nonnull)userDefaults {

}

- (void)onBackground {

}

- (void)onForeground {

}

- (void)onNotificationCreatedWithPlaceNotification:(id<PlaceNotification> _Nonnull)placeNotification created:(BOOL)created {

}

- (void)onNotificationDeletedWithPlaceNotification:(id<PlaceNotification>)placeNotification deleted:(BOOL)deleted {

}

- (void)saveWithUserDefaults:(NSUserDefaults * _Nonnull)userDefaults {

}

- (void)updateParametersWithParameters:(id _Nonnull)parameters {

}

@end

public class MyNotificationFilter: NotificationFilter {
    public func getName() -> String {
        return ""
    }

    public func createNewNotification(placeNotification: PlaceNotification) -> Bool {
        return false
    }

    public func deleteCurrentNotification(placeNotification: PlaceNotification?) -> Bool {
        return false
    }

    public func onNotificationCreated(placeNotification: PlaceNotification?, created: Bool) {

    }

    public func onNotificationDeleted(placeNotification: PlaceNotification, deleted: Bool) {

    }

    public func onBackground() {

    }

    public func onForeground() {

    }

    public func load(userDefaults: UserDefaults) {

    }

    public func save(userDefaults: UserDefaults) {

    }

    public func updateParameters(parameters: AnyObject) {

    }
}

Step 4: Register the Notification Filter

  • First, define the key of your custom filter. For example:

Switch to Swift

- (NSString * _Nonnull)getName {
    return @"MyNotificationFilter";
}
public func getName() -> String {
    return "MyNotificationFilter"
}
  • Open the AppDelegate.m file
  • In the didFinishLaunchingWithOptions method, register the MyNotificationFilter class

Switch to Swift

- (BOOL)application:(UIApplication *) application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [...]
    [[HerowDetectionManager shared] registerNotificationFilter:[MyNotificationFilter alloc]];
    [...]
}
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
    [...]
    HerowDetectionManager.shared.registerNotificationFilter(MyNotificationFilter())
    [...]
}

Step 5: Experiment with the Custom Notification Filter

  • Experiment with the default configuration: in the MyNotificationFilter file, the createNewNotification method returns false.

Switch to Swift

- (BOOL)createNewNotificationWithPlaceNotification:(id<PlaceNotification> _Nonnull)placeNotification {
    return false;
}
public func createNewNotification(placeNotification: PlaceNotification) -> Bool {
    return false
}

Note:

This means that the Notification Filter prevents the creation of any notification.

  • You can launch the application to verify this, using the testing procedure described in the notification creation tutorial
  • Now, make the createNewNotification method return true:

Switch to Swift

- (BOOL)createNewNotificationWithPlaceNotification:(id<PlaceNotification> _Nonnull)placeNotification {
    return true;
}
public func createNewNotification(placeNotification: PlaceNotification) -> Bool {
    return true
}

Note:

This means that the Notification Filter authorizes the creation of all notifications, without any filter.

  • Take a look at the deleteCurrentNotification method: it returns false

Switch to Swift

- (BOOL)deleteCurrentNotificationWithPlaceNotification:(id<PlaceNotification>)placeNotification {
    return false;
}
public func deleteCurrentNotification(placeNotification: PlaceNotification?) -> Bool {
    return false
}

Note:

This means that the notification will not be cancelled when the mobile phone exits the zones. If the notification is not cancelled, the SDK cannot display a new notification.

Therefore, in this example, only the first notification is displayed, and keeps being displayed until the user cancels it. If the user cancels the notification, no new notification is displayed.

Step 6: Implement a real-life Custom Notification Strategy

Let’s continue the tutorial with the implementation of a Custom Notification Filter that limits the number of notifications a user will see, by defining a minimum time span between two local notifications.

  • In the MyNotificationFilter file
    • add a minTimeBetweenNotification parameter
    • declare a constructor with a minTimeBetweenNotification parameter

Switch to Swift

@interface MyNotificationFilter: NSObject <NotificationFilter> {
    double minTimeBetweenNotification;
}

-(id) initWithMinTimeBetweenNotification:(double)minTimeBetweenNotification;

@end
public class MyNotificationFilter: NotificationFilter {
    let minTimeBetweenNotification : Double

    init(_ minTimeBetweenNotification: Double) {
    }
    [...]
}
  • In the MyNotificationFilter.m file, implement the newly declared constructor

Switch to Swift

-(id) initWithMinTimeBetweenNotification:(double)minTimeBetweenNotification{
    self = [super init];
    if(self){
        self->minTimeBetweenNotification = (double) minTimeBetweenNotification;
    }
    return self;
}
init(_ minTimeBetweenNotification: Double) {
    self.minTimeBetweenNotification = minTimeBetweenNotification
}
  • In the ApplicationDelegate file, update the MyNotificationFilter declaration, and set a time span of 5 minutes between each notification:

Switch to Swift

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [...]
    [[HerowDetectionManager shared] registerNotificationFilter:[[MyNotificationFilter alloc] initWithMinTimeBetweenNotification:5 * 60]];
    [...]
}
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
    [...]
    HerowDetectionManager.shared.registerNotificationFilter(MyNotificationFilter(timeBetweenNotification: 5 * 60))
    [...]
}
  • Back in the MyNotificationFilter file, add a minNextTimeNotification parameter to define the next time that a notification can be displayed.

Note:

The minNextTimeNotification is an essential parameter that must be saved and restored after an application is killed and restarted.

This can be achieved using the load and save methods. The SDK calls these methods at the best time and uses a UserDefaults to save the data.

  • In the MyNotificationFilter file, create a static MIN_NEXT_TIME_NOTIFICATION, which will be used as a key to save and load the minNextTimeNotification data.

Switch to Swift

#define MIN_NEXT_TIME_NOTIFICATION @"com.notification.minNextTimeNotification"

@interface MyNotificationFilter: NSObject <NotificationFilter> {
    double minTimeBetweenNotification;
    double minNextTimeNotification;
}
public class MyNotificationFilter: NotificationFilter {
    let static MIN_NEXT_TIME_NOTIFICATION: String = "com.notification.minNextTimeNotification"
    let minTimeBetweenNotification: Double
    var minNextTimeNotification: Double
    [...]
}

Note:

Make sure that you choose a key that is truly unique, because the UserDefaults is common to all notification filters.

  • In the NotificationFilter, implement the save and load methods in order to save and load the minNextTimeNotification parameter

Switch to Swift

- (void)loadWithUserDefaults:(NSUserDefaults * _Nonnull)userDefaults {
    minNextTimeNotification = [userDefaults doubleForKey:MIN_NEXT_TIME_NOTIFICATION];
}

- (void)saveWithUserDefaults:(NSUserDefaults * _Nonnull)userDefaults {
    [userDefaults setDouble:minNextTimeNotification forKey:MIN_NEXT_TIME_NOTIFICATION];
}
public func load(userDefaults: UserDefaults) {
    minNextTimeNotification = userDefaults.double(forKey: MIN_NEXT_TIME_NOTIFICATION)
}

public func save(userDefaults: UserDefaults) {
    userDefaults.set(minNextTimeNotification, forKey: MIN_NEXT_TIME_NOTIFICATION)
}
  • In the createNewNotification method, use the minNextTimeNotification parameter to define when the SDK is authorized to notify/let the application create a notification.

Switch to Swift

- (BOOL)createNewNotificationWithPlaceNotification:(id<PlaceNotification> _Nonnull)placeNotification {
    return minNextTimeNotification < CACurrentMediaTime();
}
public func createNewNotification(placeNotification: PlaceNotification) -> Bool {
    return self.minNextTimeNotification < CACurrentMediaTime()
}
  • As the goal of this tutorial is only to limit the number of notifications a user can see, no change will be made to the default cancellation process. As such, the deleteCurrentNotification method must return true to let the SDK cancel the notification normally.

Switch to Swift

- (BOOL)deleteCurrentNotificationWithPlaceNotification:(id<PlaceNotification>)placeNotification {
    return true;
}
public func deleteCurrentNotification(placeNotification: PlaceNotification?) -> Bool {
    return true
}
  • Once the notification has been deleted, update the minNextTimeNotification parameter, in order to define when a new notification can be displayed

Switch to Swift

- (void)onNotificationDeletedWithPlaceNotification:(id<PlaceNotification>)placeNotification deleted:(BOOL)deleted {
    if (deleted) {
        minNextTimeNotification = CACurrentMediaTime() + minTimeBetweenNotification;
    }
}
public func onNotificationDeleted(placeNotification: PlaceNotification?, deleted: Bool) {
    if deleted {
        minNextTimeNotification = CACurrentMediaTime() + minTimeBetweenNotification;
    }
}

Note 1:

Keep in mind that even if the specific Notification Filter that you have just implemented always deletes the notification, this is not necessarily the case for all of the Notification Filters that will be added to your application.

Therefore:

  • do not update any parameters in the deleteCurrentNotification method, because other filters may require that the notification stays, even when the phone exits the zone’s range
  • always do it through the onNotificationDeleted method after checking the deletion status

Similarly, do not use the createNewNotification method to update parameters, but always use the onNotificationCreated method after checking the creation status

Note 2:

The following methods allow you to update your notification strategy parameters for specific occasions:

  • onBackground: when the application switches from foreground to background
  • onForeground: when the application switches from background to foreground

Step 7: Start testing

Refer to our quick start tutorial to test the project