PETR DVOŘÁK
CEO at Lime
Push notifications.
The big way.
Should be part of every app.
Are not part of every app.
Are simple when done simple.
Mostly, they are pretty hard.
Push notifications
Why?
Users who opt in to push messages averaged 3x more
app launches than those who opted out.
— Localytics
65% of users returned to an app in the 30 days after
the app’s initial download, if they have push enabled.
— Localytics
Forced social login
Privacy concerns
Intrusive ads
Bad UI/UX
Freezing
Complex sign-up
Annoying notifications
0 20 40 60 80
71%
68%
48%
42%
29%
23%
19%
Top 7 reasons why people uninstall mobile apps
Source: Appiterate Survey, as % of all respondent (each respondent picked 3 reasons)
Personalized and relevant content.
Delivered in the right time.
Spamming users results in uninstalls.
Test, measure, improve.
Automate engagement.
When it works?
Utility & Finance
Taxi & Ride sharing
Travel & Hospitality
Sport
Food & Beverage
Media
Social
Retail & e-commerce
0 10 20 30 40
11%
13%
19%
25%
26%
29%
30%
40%
Push notification engagement by industry
Source: Kahuna
In 2015, 49.8% of app users opted in to receiving
push notifications. In 2014, it was 52.0%.
— Localytics
Implementation topics
APNs / GCM
Provider
1. Register device at APNs and provider.
2. Identify (or segment) users.
3. Send push notifications.
4. Analyze data.
5. Remove unused devices.
What needs to be done?
Device registration
Registration
APNs
Provider
1. Ask for APNs token.
Registration
APNs
Provider
1. Ask for APNs token.
2. Get APNs token
Registration
APNs
Provider
1. Ask for APNs token.
2. Get APNs token
3. Send APNs token to provider
APNs token
User identifier
Push notification settings
User demographics
User location
… and much more :-)
Data sent to provider
- (BOOL)application:(UIApplication *)app
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationType types = UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *set =
[UIUserNotificationSettings settingsForTypes:types
categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:set];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
AppDelegate.m
Register for remote notifications
- (BOOL)application:(UIApplication *)app
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationType types = UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *set =
[UIUserNotificationSettings settingsForTypes:types
categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:set];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
AppDelegate.m
Register for remote notifications
- (BOOL)application:(UIApplication *)app
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationType types = UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *set =
[UIUserNotificationSettings settingsForTypes:types
categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:set];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
AppDelegate.m
Register for remote notifications
- (BOOL)application:(UIApplication *)app
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIUserNotificationType types = UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *set =
[UIUserNotificationSettings settingsForTypes:types
categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:set];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
AppDelegate.m
Register for remote notifications
- (void)application:(UIApplication *)app
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
self.registered = YES;
[self sendProviderDeviceToken:devToken]; // custom method
}
- (void)application:(UIApplication *)app
didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSLog(@"Error in registration. Error: %@", err);
}
AppDelegate.m
Register for remote notifications
- (void)application:(UIApplication *)app
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
self.registered = YES;
[self sendProviderDeviceToken:devToken]; // custom method
}
- (void)application:(UIApplication *)app
didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSLog(@"Error in registration. Error: %@", err);
}
AppDelegate.m
Register for remote notifications
Sending notifications
Send push notifications
APNs
Provider
1. Decide to send push
Send push notifications
APNs
Provider
1. Decide to send push
2. Send payload and APNs token
Send push notifications
APNs
Provider
1. Decide to send push
2. Send payload and APNs token
3. Deliver the push message
Push notification payload
{
"aps" : {
"alert" : {
"title" : "Hello there!",
"body" : "It has been a while."
}
}
}
Maximum payload length is 4096 bytes.
Ehm… security?
Ehm… security?
Push Certifikát (*.pem, *.p12)
$ openssl pkcs12 -in apns-dev-cert.p12
-out apns-dev-cert.pem -nodes -clcerts
Ehm… security?
Push Certifikát (*.pem, *.p12)
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
$devices = new DeviceCollection(array(
new Device('???????')
));
$message = new Message('Hello guys!');
$push = new Push($apnsAdapter, $devices, $message);
$pushManager->add($push);
$pushManager->push();
Send push notifications
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
$devices = new DeviceCollection(array(
new Device('???????')
));
$message = new Message('Hello guys!');
$push = new Push($apnsAdapter, $devices, $message);
$pushManager->add($push);
$pushManager->push();
Send push notifications
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
$devices = new DeviceCollection(array(
new Device('???????')
));
$message = new Message('Hello guys!');
$push = new Push($apnsAdapter, $devices, $message);
$pushManager->add($push);
$pushManager->push();
Send push notifications
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
$devices = new DeviceCollection(array(
new Device('???????')
));
$message = new Message('Hello guys!');
$push = new Push($apnsAdapter, $devices, $message);
$pushManager->add($push);
$pushManager->push();
Send push notifications
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
$devices = new DeviceCollection(array(
new Device('???????')
));
$message = new Message('Hello guys!');
$push = new Push($apnsAdapter, $devices, $message);
$pushManager->add($push);
$pushManager->push();
Send push notifications
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
$devices = new DeviceCollection(array(
new Device('???????')
));
$message = new Message('Hello guys!');
$push = new Push($apnsAdapter, $devices, $message);
$pushManager->add($push);
$pushManager->push();
Send push notifications
- (BOOL)application:(UIApplication *)app
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *localNotif =
launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
NSDictionary *userInfo = localNotif.userInfo;
}
- (void) application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
Handle push notifications
- (BOOL)application:(UIApplication *)app
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *localNotif =
launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
NSDictionary *userInfo = localNotif.userInfo;
}
- (void) application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
Handle push notifications
- (BOOL)application:(UIApplication *)app
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *localNotif =
launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
NSDictionary *userInfo = localNotif.userInfo;
}
- (void) application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
Handle push notifications
Feedback service
Feedback service
APNs
Provider
1. Request expired tokens
Feedback service
APNs
Provider
1. Request expired tokens
2. Expired token list
Feedback service
APNs
Provider
1. Request expired tokens
2. Expired token list
3. Delete tokens
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
$feedback = $pushManager->getFeedback($apnsAdapter);
// $feedback contains collection of [device_token, timestamp] pairs
Clean up device tokens
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
$feedback = $pushManager->getFeedback($apnsAdapter);
// $feedback contains collection of [device_token, timestamp] pairs
Clean up device tokens
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
$feedback = $pushManager->getFeedback($apnsAdapter);
// $feedback contains collection of [device_token, timestamp] pairs
Clean up device tokens
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
$feedback = $pushManager->getFeedback($apnsAdapter);
// $feedback contains collection of [device_token, timestamp] pairs
Clean up device tokens
Silent push notifcation
Interactive actions
Localization
Badge number
Custom sound
Extras
Scaling big
User management - fast segmentation… by what?
Delivery time - 100k devices x 4096 … 1M devices?
Multiple apps - Reusing the push server
Hardware and infrastructure
Engineering - project grows big, multiple platforms
Dimensions of scaling
APNS / GCM
Provider
APNs
Provider
(business logic)
GCM
SDK SDK
App Management Service
Device Registration Service
User Segmentation Service
Analytics Data Service
APNS Node GCM Node
APNs
Provider
(business logic)
App Management Service
Device Registration Service
User Segmentation Service
Analytics Data Service
GCM
APNS Node GCM Node
SDK SDK
APNs
Provider
(business logic)
GCM
SDK SDK
APP KEY
App Management Service
Device Registration Service
User Segmentation Service
Analytics Data Service
APNS Node GCM Node
APP KEYAPP KEY
1. Create campaign object
2. Select the audience
3. Send notifications
4. Collect analytics
Campaign planning
APNs
Provider
(business logic)
GCM
SDK SDK
App Management Service
Device Registration Service
User Segmentation Service
Analytics Data Service
APNS Node GCM Node
APNs
Provider
(business logic)
GCM
SDK SDK
App Management Service
Device Registration Service
User Segmentation Service
Analytics Data Service
APNS Node GCM Node
APNs
Provider
(business logic)
GCM
SDK SDKApp Management Service
Device Registration Service
User Segmentation Service
Analytics Data Service
MongoDBMongoDBMongoDB
APNS Node GCM Node
N instances
Partitioning
APNs GCM
SDK SDK
API, admin, workers
IBM Bluemix - price, HW scaling, connectivity, …
MongoDB - performance, queries, … (Compose)
Node.js - for “nodes”, speed, efficiency, …
RESTful API - standards, easy to work with, … (PHP, Nette)
Server Technologies
Device registration
Push notification processing
UI Features
User profile synchronization
Location monitoring
Analytics
Mobile SDK
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions {
LimeEngate *lime = [LimeEngage sharedInstance];
[lime startFetchingContextForApplicationKey:@“app_8cb31c49a46df1fea11"];
[lime handleRemoteNotificationInfo:[launchOptions
objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]];
return YES;
}
Set up SDK
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions {
LimeEngate *lime = [LimeEngage sharedInstance];
[lime startFetchingContextForApplicationKey:@"app_8cb31c49a46df1fea11"];
[lime handleRemoteNotificationInfo:[launchOptions
objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]];
return YES;
}
Set up SDK
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions {
LimeEngate *lime = [LimeEngage sharedInstance];
[lime startFetchingContextForApplicationKey:@"app_8cb31c49a46df1fea11"];
[lime handleRemoteNotificationInfo:[launchOptions
objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]];
return YES;
}
Handle notifications
- (void) application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
LimeEngage *lime = [LimeEngage sharedInstance];
[lime handleRemoteNotificationInfo:userInfo];
}
Handle notifications
- (void) application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
LimeEngage *lime = [LimeEngage sharedInstance];
[lime handleRemoteNotificationInfo:userInfo];
}
Handle notifications
LimeEngage *lime = [LimeEngage sharedInstance];
lime.currentUser.internalId = @"4378924";
lime.currentUser.name = @"Jan";
lime.currentUser.surname = @"Novak";
lime.currentUser.sex = @"male";
[lime synchronizeCurrentUser];
Update user info
LimeEngage *lime = [LimeEngage sharedInstance];
lime.currentUser.internalId = @"4378924";
lime.currentUser.name = @"Jan";
lime.currentUser.surname = @"Novak";
lime.currentUser.sex = @"male";
[lime synchronizeCurrentUser];
Update user info
Demo
Open-source
04/2016
Thank you! :)
@joshis_tweets http://getlime.io/
WWW.MDEVTALK.CZ
mdevtalk

Petr Dvořák: Push notifikace ve velkém

  • 2.
  • 3.
  • 4.
    Should be partof every app. Are not part of every app. Are simple when done simple. Mostly, they are pretty hard. Push notifications
  • 5.
  • 6.
    Users who optin to push messages averaged 3x more app launches than those who opted out. — Localytics
  • 7.
    65% of usersreturned to an app in the 30 days after the app’s initial download, if they have push enabled. — Localytics
  • 8.
    Forced social login Privacyconcerns Intrusive ads Bad UI/UX Freezing Complex sign-up Annoying notifications 0 20 40 60 80 71% 68% 48% 42% 29% 23% 19% Top 7 reasons why people uninstall mobile apps Source: Appiterate Survey, as % of all respondent (each respondent picked 3 reasons)
  • 9.
    Personalized and relevantcontent. Delivered in the right time. Spamming users results in uninstalls. Test, measure, improve. Automate engagement. When it works?
  • 10.
    Utility & Finance Taxi& Ride sharing Travel & Hospitality Sport Food & Beverage Media Social Retail & e-commerce 0 10 20 30 40 11% 13% 19% 25% 26% 29% 30% 40% Push notification engagement by industry Source: Kahuna
  • 11.
    In 2015, 49.8%of app users opted in to receiving push notifications. In 2014, it was 52.0%. — Localytics
  • 13.
  • 14.
  • 15.
    1. Register deviceat APNs and provider. 2. Identify (or segment) users. 3. Send push notifications. 4. Analyze data. 5. Remove unused devices. What needs to be done?
  • 16.
  • 17.
  • 18.
    Registration APNs Provider 1. Ask forAPNs token. 2. Get APNs token
  • 19.
    Registration APNs Provider 1. Ask forAPNs token. 2. Get APNs token 3. Send APNs token to provider
  • 20.
    APNs token User identifier Pushnotification settings User demographics User location … and much more :-) Data sent to provider
  • 21.
    - (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert; UIUserNotificationSettings *set = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:set]; [[UIApplication sharedApplication] registerForRemoteNotifications]; } AppDelegate.m Register for remote notifications
  • 22.
    - (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert; UIUserNotificationSettings *set = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:set]; [[UIApplication sharedApplication] registerForRemoteNotifications]; } AppDelegate.m Register for remote notifications
  • 23.
    - (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert; UIUserNotificationSettings *set = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:set]; [[UIApplication sharedApplication] registerForRemoteNotifications]; } AppDelegate.m Register for remote notifications
  • 24.
    - (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert; UIUserNotificationSettings *set = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:set]; [[UIApplication sharedApplication] registerForRemoteNotifications]; } AppDelegate.m Register for remote notifications
  • 25.
    - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)devToken { self.registered = YES; [self sendProviderDeviceToken:devToken]; // custom method } - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { NSLog(@"Error in registration. Error: %@", err); } AppDelegate.m Register for remote notifications
  • 26.
    - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)devToken { self.registered = YES; [self sendProviderDeviceToken:devToken]; // custom method } - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { NSLog(@"Error in registration. Error: %@", err); } AppDelegate.m Register for remote notifications
  • 27.
  • 28.
  • 29.
    Send push notifications APNs Provider 1.Decide to send push 2. Send payload and APNs token
  • 30.
    Send push notifications APNs Provider 1.Decide to send push 2. Send payload and APNs token 3. Deliver the push message
  • 31.
    Push notification payload { "aps": { "alert" : { "title" : "Hello there!", "body" : "It has been a while." } } } Maximum payload length is 4096 bytes.
  • 32.
  • 33.
  • 37.
    $ openssl pkcs12-in apns-dev-cert.p12 -out apns-dev-cert.pem -nodes -clcerts
  • 38.
  • 39.
    $pushManager = newPushManager(PushManager::ENVIRONMENT_DEV); $apnsAdapter = new ApnsAdapter(array( 'certificate' => '/path/to/your/apns-certificate.pem', )); $devices = new DeviceCollection(array( new Device('???????') )); $message = new Message('Hello guys!'); $push = new Push($apnsAdapter, $devices, $message); $pushManager->add($push); $pushManager->push(); Send push notifications
  • 40.
    $pushManager = newPushManager(PushManager::ENVIRONMENT_DEV); $apnsAdapter = new ApnsAdapter(array( 'certificate' => '/path/to/your/apns-certificate.pem', )); $devices = new DeviceCollection(array( new Device('???????') )); $message = new Message('Hello guys!'); $push = new Push($apnsAdapter, $devices, $message); $pushManager->add($push); $pushManager->push(); Send push notifications
  • 41.
    $pushManager = newPushManager(PushManager::ENVIRONMENT_DEV); $apnsAdapter = new ApnsAdapter(array( 'certificate' => '/path/to/your/apns-certificate.pem', )); $devices = new DeviceCollection(array( new Device('???????') )); $message = new Message('Hello guys!'); $push = new Push($apnsAdapter, $devices, $message); $pushManager->add($push); $pushManager->push(); Send push notifications
  • 42.
    $pushManager = newPushManager(PushManager::ENVIRONMENT_DEV); $apnsAdapter = new ApnsAdapter(array( 'certificate' => '/path/to/your/apns-certificate.pem', )); $devices = new DeviceCollection(array( new Device('???????') )); $message = new Message('Hello guys!'); $push = new Push($apnsAdapter, $devices, $message); $pushManager->add($push); $pushManager->push(); Send push notifications
  • 43.
    $pushManager = newPushManager(PushManager::ENVIRONMENT_DEV); $apnsAdapter = new ApnsAdapter(array( 'certificate' => '/path/to/your/apns-certificate.pem', )); $devices = new DeviceCollection(array( new Device('???????') )); $message = new Message('Hello guys!'); $push = new Push($apnsAdapter, $devices, $message); $pushManager->add($push); $pushManager->push(); Send push notifications
  • 44.
    $pushManager = newPushManager(PushManager::ENVIRONMENT_DEV); $apnsAdapter = new ApnsAdapter(array( 'certificate' => '/path/to/your/apns-certificate.pem', )); $devices = new DeviceCollection(array( new Device('???????') )); $message = new Message('Hello guys!'); $push = new Push($apnsAdapter, $devices, $message); $pushManager->add($push); $pushManager->push(); Send push notifications
  • 45.
    - (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { UILocalNotification *localNotif = launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; NSDictionary *userInfo = localNotif.userInfo; } - (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { } Handle push notifications
  • 46.
    - (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { UILocalNotification *localNotif = launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; NSDictionary *userInfo = localNotif.userInfo; } - (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { } Handle push notifications
  • 47.
    - (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { UILocalNotification *localNotif = launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; NSDictionary *userInfo = localNotif.userInfo; } - (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { } Handle push notifications
  • 48.
  • 49.
  • 50.
    Feedback service APNs Provider 1. Requestexpired tokens 2. Expired token list
  • 51.
    Feedback service APNs Provider 1. Requestexpired tokens 2. Expired token list 3. Delete tokens
  • 52.
    $pushManager = newPushManager(PushManager::ENVIRONMENT_DEV); $apnsAdapter = new ApnsAdapter(array( 'certificate' => '/path/to/your/apns-certificate.pem', )); $feedback = $pushManager->getFeedback($apnsAdapter); // $feedback contains collection of [device_token, timestamp] pairs Clean up device tokens
  • 53.
    $pushManager = newPushManager(PushManager::ENVIRONMENT_DEV); $apnsAdapter = new ApnsAdapter(array( 'certificate' => '/path/to/your/apns-certificate.pem', )); $feedback = $pushManager->getFeedback($apnsAdapter); // $feedback contains collection of [device_token, timestamp] pairs Clean up device tokens
  • 54.
    $pushManager = newPushManager(PushManager::ENVIRONMENT_DEV); $apnsAdapter = new ApnsAdapter(array( 'certificate' => '/path/to/your/apns-certificate.pem', )); $feedback = $pushManager->getFeedback($apnsAdapter); // $feedback contains collection of [device_token, timestamp] pairs Clean up device tokens
  • 55.
    $pushManager = newPushManager(PushManager::ENVIRONMENT_DEV); $apnsAdapter = new ApnsAdapter(array( 'certificate' => '/path/to/your/apns-certificate.pem', )); $feedback = $pushManager->getFeedback($apnsAdapter); // $feedback contains collection of [device_token, timestamp] pairs Clean up device tokens
  • 56.
    Silent push notifcation Interactiveactions Localization Badge number Custom sound Extras
  • 57.
  • 58.
    User management -fast segmentation… by what? Delivery time - 100k devices x 4096 … 1M devices? Multiple apps - Reusing the push server Hardware and infrastructure Engineering - project grows big, multiple platforms Dimensions of scaling
  • 59.
  • 60.
    APNs Provider (business logic) GCM SDK SDK AppManagement Service Device Registration Service User Segmentation Service Analytics Data Service APNS Node GCM Node
  • 61.
    APNs Provider (business logic) App ManagementService Device Registration Service User Segmentation Service Analytics Data Service GCM APNS Node GCM Node SDK SDK
  • 62.
    APNs Provider (business logic) GCM SDK SDK APPKEY App Management Service Device Registration Service User Segmentation Service Analytics Data Service APNS Node GCM Node APP KEYAPP KEY
  • 63.
    1. Create campaignobject 2. Select the audience 3. Send notifications 4. Collect analytics Campaign planning
  • 64.
    APNs Provider (business logic) GCM SDK SDK AppManagement Service Device Registration Service User Segmentation Service Analytics Data Service APNS Node GCM Node
  • 65.
    APNs Provider (business logic) GCM SDK SDK AppManagement Service Device Registration Service User Segmentation Service Analytics Data Service APNS Node GCM Node
  • 66.
    APNs Provider (business logic) GCM SDK SDKAppManagement Service Device Registration Service User Segmentation Service Analytics Data Service MongoDBMongoDBMongoDB APNS Node GCM Node N instances Partitioning
  • 67.
    APNs GCM SDK SDK API,admin, workers
  • 68.
    IBM Bluemix -price, HW scaling, connectivity, … MongoDB - performance, queries, … (Compose) Node.js - for “nodes”, speed, efficiency, … RESTful API - standards, easy to work with, … (PHP, Nette) Server Technologies
  • 69.
    Device registration Push notificationprocessing UI Features User profile synchronization Location monitoring Analytics Mobile SDK
  • 70.
    - (BOOL)application:(UIApplication *)appdidFinishLaunchingWithOptions: (NSDictionary *)launchOptions { LimeEngate *lime = [LimeEngage sharedInstance]; [lime startFetchingContextForApplicationKey:@“app_8cb31c49a46df1fea11"]; [lime handleRemoteNotificationInfo:[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]]; return YES; } Set up SDK
  • 71.
    - (BOOL)application:(UIApplication *)appdidFinishLaunchingWithOptions: (NSDictionary *)launchOptions { LimeEngate *lime = [LimeEngage sharedInstance]; [lime startFetchingContextForApplicationKey:@"app_8cb31c49a46df1fea11"]; [lime handleRemoteNotificationInfo:[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]]; return YES; } Set up SDK
  • 72.
    - (BOOL)application:(UIApplication *)appdidFinishLaunchingWithOptions: (NSDictionary *)launchOptions { LimeEngate *lime = [LimeEngage sharedInstance]; [lime startFetchingContextForApplicationKey:@"app_8cb31c49a46df1fea11"]; [lime handleRemoteNotificationInfo:[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]]; return YES; } Handle notifications
  • 73.
    - (void) application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary *)userInfo { LimeEngage *lime = [LimeEngage sharedInstance]; [lime handleRemoteNotificationInfo:userInfo]; } Handle notifications
  • 74.
    - (void) application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary *)userInfo { LimeEngage *lime = [LimeEngage sharedInstance]; [lime handleRemoteNotificationInfo:userInfo]; } Handle notifications
  • 75.
    LimeEngage *lime =[LimeEngage sharedInstance]; lime.currentUser.internalId = @"4378924"; lime.currentUser.name = @"Jan"; lime.currentUser.surname = @"Novak"; lime.currentUser.sex = @"male"; [lime synchronizeCurrentUser]; Update user info
  • 76.
    LimeEngage *lime =[LimeEngage sharedInstance]; lime.currentUser.internalId = @"4378924"; lime.currentUser.name = @"Jan"; lime.currentUser.surname = @"Novak"; lime.currentUser.sex = @"male"; [lime synchronizeCurrentUser]; Update user info
  • 77.
  • 78.
  • 79.
    Thank you! :) @joshis_tweetshttp://getlime.io/
  • 80.