Skip to content

Instantly share code, notes, and snippets.

@nursarowar
Created May 27, 2017 13:36
Show Gist options
  • Select an option

  • Save nursarowar/1ad9638130615b766d44890d5eb07573 to your computer and use it in GitHub Desktop.

Select an option

Save nursarowar/1ad9638130615b766d44890d5eb07573 to your computer and use it in GitHub Desktop.
(iOS) Server Push Notifications
The architecture of Push Notification consists of three key pieces:
1. iOS Application – that enables push notification and registers the device for notification
2. Application Server – is responsible for generating the messages and publishing them to the Apple Push Notification Service (APNS)
3.Apple Push Notification Service (APNS) – is responsible for delivering the messages to the devices where the application is installed
HOW TO GET a PUSH CERTIFICATION
http://b2cloud.com.au/how-to-guides/ios-push-notifications-in-php
Also check these:
PHP classes that handle Apple's Push Notifications
https://code.google.com/p/apns-php/
HOWTO: http://weblog.plexobject.com/?p=1680
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Popup to the user if they want to receive notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
return YES;
}
//Push Notifications delegate
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
/* OR
const unsigned* tokenBytes = [deviceToken bytes];
NSString* deviceTokenString = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
*/
NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<> "]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
//Custom class
//Inform the server of this device token.
//This will be used by the server to send the Push Notification
DeviceRegisterer *registrar = [[DeviceRegisterer alloc] init];
[registrar registerDeviceWithToken:token];
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSLog(@"failed to regiser %@", err);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(@"notification options %@", userInfo);
}
/* CAUTION
The device token is not the device id, it is not unique for the phone, and not unique per application,
and will change from development to production. Whatever device tokens you collect during development,
you must separate them from the ones you collect during production or the phone will not receive them.
So with that out of the way, you need to somehow get your device tokens to your server,
and have a way to distinguish development tokens from production tokens. I wont walk you through this part.
*/
@class ASIFormDataRequest;
@interface DeviceRegisterer : NSObject {
//used ASIHTTPRequest library for invoking REST service I wrote for registering devices
ASIFormDataRequest *request;
}
@property (retain, nonatomic) ASIFormDataRequest *request;
- (void)registerDeviceWithToken:(NSString *)token;
@end
#import "DeviceRegisterer.h"
#import "ASIFormDataRequest.h"
@implementation DeviceRegisterer
@synthesize request;
- (void)registerDeviceWithToken:(NSString *)token {
if (self.request == nil) {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/admin/apns_devices.json", API_BASE_DOMAIN]];
[self setRequest:[ASIFormDataRequest requestWithURL:url]];
[request setPostValue:token forKey:@"token"];
[request setTimeOutSeconds:30];
[request setDelegate:self];
[request setDidFailSelector:@selector(registerFailed:)];
[request setDidFinishSelector:@selector(registerFinished:)];
[request startAsynchronous];
}
}
- (void)registerFailed:(ASIHTTPRequest *)theRequest {
NSLog(@"registerFailed %@", [theRequest error]);
}
- (void)registerFinished:(ASIHTTPRequest *)theRequest {
NSLog(@"registerFinished %d",[theRequest postLength]);
}
- (void)dealloc {
[request cancel];
[request release];
[super dealloc];
}
@end
//make sure port 2195 is open for both outgoing and incoming connections.
/*
if for whatever reason you send a bad device token or a development token during production (or vice versa)
to the APNS within the foreach loop, Apple will drop your connection,
so if not all or none of your messages are getting through, check this.
*/
$message = 'Hello';
$badge = 3;
$sound = 'default'; //or put sound filename
$development = true; //Change the $development boolean to switch between development and production pushes
$payload = array();
$payload['aps'] = array('alert' => $message, 'badge' => intval($badge), 'sound' => $sound);
$payload = json_encode($payload);
$apns_url = NULL;
$apns_cert = NULL;
$apns_port = 2195;
if($development)
{
$apns_url = 'gateway.sandbox.push.apple.com';
$apns_cert = '/path/to/cert/cert-dev.pem';
}
else
{
$apns_url = 'gateway.push.apple.com';
$apns_cert = '/path/to/cert/cert-prod.pem';
}
$stream_context = stream_context_create();
stream_context_set_option($stream_context, 'ssl', 'local_cert', $apns_cert);
$apns = stream_socket_client('ssl://' . $apns_url . ':' . $apns_port, $error, $error_string, 2, STREAM_CLIENT_CONNECT, $stream_context);
// You will need to put your device tokens into the $device_tokens array yourself
$device_tokens = array("token1","token2","token3");
foreach($device_tokens as $device_token)
{
$apns_message = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device_token)) . chr(0) . chr(strlen($payload)) . $payload;
fwrite($apns, $apns_message);
}
@socket_close($apns);
@fclose($apns);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment