How can PHP code use an APNS device token for Apple Push Notification? - apple-push-notifications

I'm looking at the PHP code here:
https://gist.github.com/valfer/18e1052bd4b160fed86e6cbb426bb9fc
It looks good. I'd love to use it. But I'm confused about this:
* #param $token the token of the device
So I need the device token? For PHP code that is going to live on a server? How do I get the device token?

when iOS application is started, it registers itself for Apple Push Notifications by using the following code in your AppDelegate's didFinishLaunchingWithOptions.
if([[[UIDevice currentDevice] systemVersion] floatValue]>=8.0) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
} else {
//register to receive notifications
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
}
and then following delegate methods may be called based on success or failure
-(void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
NSString* strdeviceToken = [[NSString alloc]init];
strdeviceToken=[self stringWithDeviceToken:deviceToken];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:strdeviceToken forKey:PREF_DEVICE_TOKEN];
[prefs synchronize];
NSLog(#"My token is===========> : %#",strdeviceToken);
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
// NSLog(#"Failed to get token, error: %#", error);
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:#"" forKey:PREF_DEVICE_TOKEN];
[prefs synchronize];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if (application.applicationState == UIApplicationStateActive) {
// [self showToastMessage:#"Active"];
}
else if (application.applicationState == UIApplicationStateBackground) {
// [self showToastMessage:#"Background"];
}
else if (application.applicationState == UIApplicationStateInactive) {
// [self showToastMessage:#"Inactive"];
}
// [self handleIncomingNotification:userInfo delay:0.0];
}
All the above logic should be handled in AppDelegate class of your project. Then you can make some API call in your PHP code to be called from iOS and send this device token on your server and save it for future use.

Related

Receiving Apple Push Notifications when app is in background

I have implemented push notifications in my iOS8 app. I am trying to play an audio file once the notification is received.
The code is playing the audio when the app is in the foreground, but when the app is in the background, nothing happens.
I have tried regenerating the certificates and provisioning profiles. And I have made sure that the app is running in the background, i.e. the user has not swiped up to remove it. In Background modes, I have enabled Remote Notifications, Background Fetch and Audio & Airplay.
I have added code snippets from my AppDelegate.m file:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// More code here ---------------------------------------------------
if (launchOptions) {
NSDictionary *userInfo = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
if (apsInfo) { //apsInfo is not nil
[self performSelector:#selector(playCarAlarmAudio)
withObject:nil
afterDelay:1];
}
}
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge
|UIUserNotificationTypeSound
|UIUserNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
// More code here ---------------------------------------------------
}
The delegate methods to handle push notifications:
-(void) application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"Failed to register for push");
}
-(void) application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[self respondToEventNotification:userInfo];
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// [self respondToEventNotification:userInfo];
[self playAlarmAudio];
}
-(void) respondToEventNotification : (NSDictionary *) userInfo {
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
[localNotification setSoundName:#"alarm.mp3"];
[localNotification setFireDate:[NSDate date]];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
else if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
[self playAlarmAudio];
}
}
And to play the Alarm:
-(void) playAlarmAudio {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"alarm" ofType:#"mp3"];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:nil];
self.audioPlayer.numberOfLoops = 1;
[self.audioPlayer play];
}
According to the following Apple documentation, the notification sound to be played is specified inside the notification payload dictionary (https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html):
The Notification Payload
Each remote notification includes a payload. The payload contains information about how the system should alert the user as well as any custom data you provide. In iOS 8 and later, the maximum size allowed for a notification payload is 2 kilobytes; Apple Push Notification service refuses any notification that exceeds this limit. (Prior to iOS 8 and in OS X, the maximum payload size is 256 bytes.)
For each notification, compose a JSON dictionary object (as defined by RFC 4627). This dictionary must contain another dictionary identified by the key aps. The aps dictionary can contain one or more properties that specify the following user notification types:
An alert message to display to the user
A number to badge the app icon with
A sound to play

iOS App not registering for push notifications

I am trying to register for push notifications in my iOS app. But it is calling neither the didRegisterForRemoteNotificationsWithDeviceToken nor didFailToRegisterForRemoteNotificationsWithError callback methods. I have revoked and regenerated the provisioning profile for the app.
I am using iOS8 and I have enabled the following background modes in my Info.plist
App registers for location updates
App downloads content in response to push notifications
App downloads content from the network
The code is:
-(void) application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(#"Failed to register for push");
}
-(void) application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(#"did succeed in register for push");
// Get the device token string
const char* data = [deviceToken bytes];
NSMutableString* token = [NSMutableString string];
for (int i = 0; i < [deviceToken length]; i++) {
[token appendFormat:#"%02.2hhX", data[i]];
}
[[NSUserDefaults standardUserDefaults] setObject:token forKey:#"DeviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[self respondToEventNotification:userInfo];
}
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[self respondToEventNotification:userInfo];
}
Have you register your app with didFinishLaunchingWithOptions method for iOS8 like,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
|UIRemoteNotificationTypeSound
|UIRemoteNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
else
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
You have to consider registration process of Push Notification in iOS8.
May this help you.

Push Notification not working in iOS 8 using Parse.com

i have a code that works in iOS 7, i receive all the Push Notifications.
When implementing the new iOS 8 Push Notification using Parse.com, i can't make it work.
Here is the code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// Register for push notifications
[Parse setApplicationId:#"XXXX" clientKey:#"XXX"]; // REMOVED IDS FOR SECURITY REAS
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
UIMutableUserNotificationAction *viewAction = [[UIMutableUserNotificationAction alloc] init];
viewAction.identifier = #"medphone-view";
viewAction.title = #"Ver";
viewAction.activationMode = UIUserNotificationActivationModeForeground;
viewAction.destructive = NO;
UIMutableUserNotificationAction *dismissAction = [[UIMutableUserNotificationAction alloc] init];
dismissAction.identifier = #"medphone-dismiss";
dismissAction.title = #"Excluir";
dismissAction.activationMode = UIUserNotificationActivationModeBackground;
dismissAction.destructive = YES;
UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
category.identifier = #"medphone";
[category setActions:[NSArray arrayWithObjects:viewAction, dismissAction, nil] forContext:UIUserNotificationActionContextDefault];
NSSet *categories = [NSSet setWithObjects:category, nil];
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:categories];
[application registerUserNotificationSettings:mySettings];
[application registerForRemoteNotifications];
} else {
[application registerForRemoteNotificationTypes:
UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound];
}
if (launchOptions) { //launchOptions is not nil
NSDictionary *userInfo = [launchOptions valueForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"];
NSLog(#"Push info %#", userInfo);
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
if (apsInfo) { //apsInfo is not nil
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setValue:userInfo forKey:#"PUSHDATA"];
[prefs setBool:YES forKey:#"PUSH"];
[prefs synchronize];
NSLog(#"entrou no UIApplicationLaunchOptionsRemoteNotificationKey %#", apsInfo);
}
}
return YES;
}
And these other methods:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
currentInstallation.channels = #[#"global"];
[currentInstallation saveInBackground];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[[NSNotificationCenter defaultCenter] postNotificationName:#"pushNotification" object:userInfo];
NSLog(#"entrou no didReceiveRemoteNotification %#", userInfo);
}
#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler {
NSLog(#"entrou no UIApplicationLaunchOptionsRemoteNotificationKey %#", userInfo);
//handle the actions
if ([identifier isEqualToString:#"medphone-view"]) {
NSLog(#"ver");
} else if ([identifier isEqualToString:#"medphone-dismiss"]) {
NSLog(#"dismmis");
}
completionHandler();
}
#endif
Is there anything i`m doing wrong? The payload is correct, bacause its working on iOS 7. And the category is set.
Please me let me know!
The code for iOS 8 has Changed:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{ [[UIApplication sharedApplication] registerUserNotificationSettings:
[UIUserNotificationSettings settingsForTypes:
(UIUserNotificationTypeSound |
UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIUserNotificationTypeBadge |
UIUserNotificationTypeSound |
UIUserNotificationTypeAlert)];
}

how could i integrate via me social site into iphone app

hi i want to integrate Via Me social site into my iphone app,i googled but didn't find any samples.
The basic process is as follows:
Create a custom URL scheme for your app. Via Me will use this after the user has been authenticated, to return to your app. In my example, I created one called "robviame://"
Register your app at http://via.me/developers. This will give you a client id and a client secret:
When you want to authenticate the user, you call:
NSString *redirectUri = [[self redirectURI] stringByAddingPercentEscapesForURLParameterUsingEncoding:NSUTF8StringEncoding];
NSString *urlString = [NSString stringWithFormat:#"https://api.via.me/oauth/authorize/?client_id=%#&redirect_uri=%#&response_type=code", kClientID, redirectUri];
NSURL *url = [NSURL URLWithString:urlString];
[[UIApplication sharedApplication] openURL:url];
What that will do is fire up your web browser and give the user a chance to log on and grant permissions to your app. When user finishes that process, because you've defined your custom URL scheme, it will call the following method in your app delegate:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
// do whatever you want here to parse the code provided back to the app
}
for example, I'll call a handler for my Via Me response:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
ViaMeManager *viaMeManager = [ViaMeManager sharedManager];
if ([[url host] isEqualToString:viaMeManager.host])
{
[viaMeManager handleViaMeResponse:[self parseQueryString:[url query]]];
return YES;
}
return NO;
}
// convert the query string into a dictionary
- (NSDictionary *)parseQueryString:(NSString *)query
{
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
NSArray *queryParameters = [query componentsSeparatedByString:#"&"];
for (NSString *queryParameter in queryParameters) {
NSArray *elements = [queryParameter componentsSeparatedByString:#"="];
NSString *key = [elements[0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *value = [elements[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
value = [[value componentsSeparatedByString:#"+"] componentsJoinedByString:#" "];
[dictionary setObject:value forKey:key];
}
return dictionary;
}
That handler might, for example, save the code and then request the access token:
- (void)handleViaMeResponse:(NSDictionary *)parameters
{
self.code = parameters[#"code"];
if (self.code)
{
// save the code
[[NSUserDefaults standardUserDefaults] setValue:self.code forKey:kViaMeUserDefaultKeyCode];
[[NSUserDefaults standardUserDefaults] synchronize];
// now let's authenticate the user and get an access key
[self requestToken];
}
else
{
NSLog(#"%s: parameters = %#", __FUNCTION__, parameters);
NSString *errorCode = parameters[#"error"];
if ([errorCode isEqualToString:#"access_denied"])
{
[[[UIAlertView alloc] initWithTitle:nil
message:#"Via Me functions will not be enabled because you did not authorize this app"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}
else
{
[[[UIAlertView alloc] initWithTitle:nil
message:#"Unknown Via Me authorization error"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}
}
}
and the code to retrieve the token might look like:
- (void)requestToken
{
NSURL *url = [NSURL URLWithString:#"https://api.via.me/oauth/access_token"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
NSDictionary *paramsDictionary = #{#"client_id" : kClientID,
#"client_secret" : kClientSecret,
#"grant_type" : #"authorization_code",
#"redirect_uri" : [self redirectURI],
#"code" : self.code,
#"response_type" : #"token"
};
NSMutableArray *paramsArray = [NSMutableArray array];
[paramsDictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) {
[paramsArray addObject:[NSString stringWithFormat:#"%#=%#", key, [obj stringByAddingPercentEscapesForURLParameterUsingEncoding:NSUTF8StringEncoding]]];
}];
NSData *paramsData = [[paramsArray componentsJoinedByString:#"&"] dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:paramsData];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error)
{
NSLog(#"%s: NSURLConnection error = %#", __FUNCTION__, error);
return;
}
NSError *parseError;
id results = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (parseError)
{
NSLog(#"%s: NSJSONSerialization error = %#", __FUNCTION__, parseError);
return;
}
self.accessToken = results[#"access_token"];
if (self.accessToken)
{
[[NSUserDefaults standardUserDefaults] setValue:self.accessToken forKey:kViaMeUserDefaultKeyAccessToken];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}];
}
Hopefully this will be enough to get you going. This is described in greater detail at the http://via.me/developers page.

Core Data Mac OS X app and compatibilty with OS X 10.7

Hello i have created a Simple Application with Core Data and OS X 10.8, it's the simple template that xcode create, but if i change the Base SDK to 10.7 xcode give me this error on this method in App Controller:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator) {
return _persistentStoreCoordinator;
}
NSManagedObjectModel *mom = [self managedObjectModel];
if (!mom) {
NSLog(#"%#:%# No model to generate a store from", [self class], NSStringFromSelector(_cmd));
return nil;
}
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *applicationFilesDirectory = [self applicationFilesDirectory];
NSError *error = nil;
NSDictionary *properties = [applicationFilesDirectory resourceValuesForKeys:#[NSURLIsDirectoryKey] error:&error];
if (!properties) {
BOOL ok = NO;
if ([error code] == NSFileReadNoSuchFileError) {
ok = [fileManager createDirectoryAtPath:[applicationFilesDirectory path] withIntermediateDirectories:YES attributes:nil error:&error];
}
if (!ok) {
[[NSApplication sharedApplication] presentError:error];
return nil;
}
} else {
if (![properties[NSURLIsDirectoryKey] boolValue]) {
// Customize and localize this error.
NSString *failureDescription = [NSString stringWithFormat:#"Expected a folder to store application data, found a file (%#).", [applicationFilesDirectory path]];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setValue:failureDescription forKey:NSLocalizedDescriptionKey];
error = [NSError errorWithDomain:#"YOUR_ERROR_DOMAIN" code:101 userInfo:dict];
[[NSApplication sharedApplication] presentError:error];
return nil;
}
}
NSURL *url = [applicationFilesDirectory URLByAppendingPathComponent:#"SimpleApp.storedata"];
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
if (![coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error]) {
[[NSApplication sharedApplication] presentError:error];
return nil;
}
_persistentStoreCoordinator = coordinator;
return _persistentStoreCoordinator;
}
i receive this error:
how i can do?
This is actually not a problem with Core Data, but this is having to do with object subscripting. In order for these literals to work correctly, your SDK needs to be at least OS X 10.8 or iOS 6.
If there is no other way, you can still use subscripting and keep your SDK to 10.7 by adding a stub header to a category on NSObject that implements the required methods. You can see one such example here. I'd advise keeping your SDK on 10.8, however.

Resources