I've created an iphone app with push notification using Azure notification hub. But I'm having a hard time getting the push to work.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/******** code for Push notification **********/
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
NSLog(#"Entered appDelegate didFinishLaunchingWithOptions");
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *) deviceToken {
SBNotificationHub* hub = [[SBNotificationHub alloc] initWithConnectionString:#"<my azure listening connection string>" notificationHubPath:#"myhub"];
NSLog(#" DeviceToken: %#",deviceToken);
[hub registerNativeWithDeviceToken:deviceToken tags:nil completion:^(NSError* error) {
if (error != nil) {
NSLog(#"Error registering for notifications: %#", error);
}
else {
[self MessageBox:#"Registration Status" message:#"Registered"];
}
}];
}
-(void)MessageBox:(NSString *)title message:(NSString *)messageText {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:messageText delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification: (NSDictionary *)userInfo {
NSLog(#"%#", userInfo);
[self MessageBox:#"Notification" message:[[userInfo objectForKey:#"aps"] valueForKey:#"alert"]];
}
I've followed the steps form this document:
https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-ios-get-started/
I've created an explicit app id on the Member center and it matches my bundle id. I'm using developer cert and chose "sandbox" under Azure.
When I first launched my app on to my iphone (not simulator) I get the prompt to accept push notifications - I chose yes. Then my code gets a token from apple and registers that with Azure NH, which is successful.
From Azure NH debug tab, I did a broadcast send which was successfully sent from Azure to APNS. But I never received any notifications. Here is the body of the push notification message on Azure:
{"aps":{"alert":"Notification Hub test notification"}}
I have tried this multiple times and even created an isolated project just to test push notification (separate certs, provisioning profile etc) and it still does not work.
When I intentionally malform the payload of the message for Push, I do get an error as expected So it seems that the connection from NH to APNS is good.
My requirement is to send around 100 million pushes a month.
If anyone has used Azure notification for push notifications then please advice how to fix this?
If anyone has had poor experience with Azure NH then please share what you ended up migrating to.
Thanks in advance.
I was able to get this to work.
I deleted all certificates on Apple developer center and my mac. I recreated the certificates and then followed the process again. It all worked out this time.
Thanks.
Related
I am now using parse to set up Facebook login, but it will jump into Safari when I click PFLogInFieldsFacebook button. I want to have a in APP login page(UIWebView or something). I want to do that because I noticed that IOS 9 will give a back to Safari when I am back to my APP. Here is the code I am using:
PFLogInViewController *logInViewController = [[PFLogInViewController alloc] init];
[logInViewController setDelegate:self]; // Set ourselves as the delegate
// Create the sign up view controller
logInViewController.fields = PFLogInFieldsFacebook;
// Present the log in view controller
[self presentViewController:logInViewController animated:YES completion:NULL];
logInViewController.logInView.layer.contents = (id)[UIImage imageNamed:#"allow.png"].CGImage;
[logInViewController.logInView setLogo:nil];
I also find that latest Facebook SDK can do the job, but I am still getting used to using Parse. So please help me out.
After reading through parse doc, I figured out that AppDelegate.m file should be updated like this for IOS 9:
There's also two code changes you'll need to make. First, add the
following to your application:didFinishLaunchingWithOptions: method,
after you've initialized the Parse SDK.
// AppDelegate.m
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <ParseFacebookUtilsV4/PFFacebookUtils.h>
#implementation AppDelegate
- (void)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Parse setApplicationId:#"parseAppId" clientKey:#"parseClientKey"];
[PFFacebookUtils initializeFacebookWithApplicationLaunchOptions:launchOptions];
}
Next, add the following handlers in your app delegate.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
There are two main ways to use Facebook with your Parse users: (1) to
log in (or sign up) as a Facebook user and creating a PFUser, or (2)
linking Facebook to an existing PFUser.
Having two devices that need to keep transferring data while in background or in LockScreen.
The main resource about backgrounding is available on https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
So far I'm looking forward to understand how is it expected to implement such above mentioned behaviour: in a scenario where a transfer is in progress and one of the apps (or both) goes into background. Obviously we have resumable transfer management working already.
I've been collecting stubs and answers about and I've ended up with the following:
Ensure every socket is backgroundable.
[socket performBlock:^{
[socket enableBackgroundingOnSocket];
}];
To keep backgrounding even when in Lock Screen, I read an answer saying that we should have something like at the end of didFinishLaunchingWithOptions but what code is in [self backgroundHandler] method?
BOOL backgroundAccepted = [[UIApplication sharedApplication]
setKeepAliveTimeout:600 handler:^{ [self backgroundHandler]; }];
if (backgroundAccepted)
NSLog(#"background handler accepted");
return YES;
The applicationDidEnterBackground delegate method of UIApplication shows
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(#"=== DID ENTER BACKGROUND ===");
if([[UIDevice currentDevice] respondsToSelector:#selector(isMultitaskingSupported)])
NSLog(#"Multitasking Supported");
else
return;
// Shall I remove my KVO observers when in background?? I guess NOT, right? :D
//[[NSNotificationCenter defaultCenter] removeObserver:self];
UIBackgroundTaskIdentifier bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
NSLog(#"End of tolerate time. Application should be suspended now if we do not ask more 'tolerance'");
// [self askToRunMoreBackgroundTask]; This code seems to be unnecessary. I'll verify it.
}];
if (bgTask == UIBackgroundTaskInvalid)
NSLog(#"This application does not support background mode");
else
NSLog(#"Application will continue to run in background");
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
});
I got it working following this tutorial but looks like GCDAsyncSocket is no longer maintained so it will work only on iOS7.
http://www.objc.io/issue-5/multitasking.html
To do background file transfer under iOS 8 I am using AFNetworking library (http://afnetworking.com)
I already have an app in the appstore. Now I wanted to add APNS. On the developer portal I setup a developer certificate and enabled my app for APNS. I created a new provisioning
profile and set that in my app under Debug. Ive removed all other provisioning profiles.
When I run my app on my iphone, I send registerForRemoteNotificationTypes but never
get a response from apple, nor is the error delegate ever called. If I remove the app
on the iphone and re-install, it never asks about push notifications.
Ive read through as many stack overflow articles and tutorials/Apple docs on the subject in the last 2 days as I can find and nothing seems to fix my issue thus far.
Other things Ive checked:
- Checked the Entitlements.plist file for bad keys
- Checked the downloaded .mobileprovision file for aps-environment with development string
- Removed every other provision profile in my Organizer -> Device as well as the Keychain
- Changed the date on my iphone to a day forward, powered off, powered on, reloaded app
Does anyone have any other suggestions on what to try or an answer as to why trying to
setup APNS on an existing app doesnt seem to work?
Note that Im trying to develop a new version with APNS, not asking why the released
version doesnt work yet. Once I can debug with APNS, then Ill go for the disto APNS.
Thanks in advance.
[EDIT] I think you misunderstood my question. Ive already read through the docs and
gone through the steps. In fact, this same code worked at one time and I disabled it
temporarily a couple major revs ago, but now want to re-enable it. Ive also seen that
same Tutorial. The main problem as far as I can tell is NOT my code, its the provision
profile or something to do with a bug with Apple and how its handling the push certificate
in an existing file or something.
Here's my code, but as I said, I dont think its my code at this point, its something with
the provisioning or something. Ive verified I call this, but never get a callback to
one of the delegates after getting the push certificate setup on the IOS Dev site as well
as getting a new provisioning profile WITH push in it.
[application registerForRemoteNotificationTypes:
(UIRemoteNotificationType)
(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert) ];
Delegates never get called:
- (void) application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[Log log:TINFO :#"==== APNS didRegisterForRemoteNotifcationsWithDeviceToken ===="];
NSString *devtok = [NSString stringWithFormat:#"%#",deviceToken];
devtok = [devtok stringByReplacingOccurrencesOfString: #"" withString: #""];
devtok = [devtok stringByReplacingOccurrencesOfString: #" " withString: #""];
NSString *stok = [[[NSString alloc] initWithFormat:#"%#", devtok] autorelease];
[Log log:TINFO :#"saving ", devtok];
UpdateDevToken *utok = [[UpdateDevToken alloc] autorelease];
[utok updateDeviceToken:stok];
}
Error Delegate:
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[Log log:TERR :#"==== APNS didFailToRegisterForRemoteNotificationsWithError: %#", error.localizedDescription];
}
[Edit 2] Forgot to add that I also have didReceiveRemoteNotification:
- (void)application:(UIApplication *)application didReceiveRemoteNotification(NSDictionary *)userInfo
{
[Log log:TENT :#"==== APNS didReceiveRemoteNotification"];
}
None of my delegates ever get called.
To start with See Apple doc on APNS.
Check out the Raywander Tutorial.
Then modify our AppDelegate Class.
// Add This to did to
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
........
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
return YES;
}
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults valueForKey:#"device_token"]) { // Check existing device token
NSLog(#"My saved token is: %#", [defaults valueForKey:#"device_token"]);
}
NSString *deviceTokenString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
deviceTokenString = [deviceTokenString stringByReplacingOccurrencesOfString:#" " withString:#""];
[defaults setObject:deviceTokenString forKey:#"device_token"];
[defaults synchronize];
NSLog(#"My token is: %#", deviceTokenString);
}
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(#"Failed to get token, error: %#", error);
//[self showAlertMessage:#"Failed to get token, error!"];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"userInfo :%#",userInfo);
//[self setUser:[[userInfo valueForKey:#"aps"] valueForKey:#"alert"]];
}
I have a push notification that I am sending to a user and I want to be able to take an action when they tap on it. I know that if the app is in the foreground, background, or if the user taps on the alert from the notification center that the following method is called in the app delegate:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
However, if the app is not launched and the user taps on a notification banner as soon as the notification arrives, this method does not seem to get called. Is their a different method that I need to impliment in this situation? Are their other cases where other methods should be implemented as well?
If you app is not launched when clicking on a notification banner, then you will receive an NSDictionary in your application:didFinishLaunchingWithOptions:.
Then you can just do something like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *pushDict = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(pushDict)
{
[self application:application didReceiveRemoteNotification:pushDict];
}
}
Additionally, in your application:didReceiveRemoteNtification: method, you can test if your application was inactive at the time the notification was received, like this:
-(void)application:(UIApplication *)app didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if([app applicationState] == UIApplicationStateInactive)
{
NSLog(#"Received notifications while inactive.");
}
else
{
NSLog(#"Received notifications while active.");
}
I have never coded an App with Push Notifications and I have a very general question.
I would like to refresh a UITableview's data (coming from a webservice) automaticaly without "pull to refresh" or any other user's interaction. Is it possible to use Push notifications to inform my app for a data change, in order to avoid polling every xx seconds wasting bandwidth and battery?
In other words, while my app runs in the foreground (maybe) I can handle the message and the user wont receive a popup but what happens otherwise?
Is there any other way to achieve the same result?
I am going to use IOS 5.0+
Thanks in Advance
You could make a server HTTP-Request which only returns something if there was a change. Then in case this response is not empty you can reload the data. The function you can call by a NSTimer.
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(get) userInfo:nil repeats:YES];
and
-(void)get {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://example.com/app.php"]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if(![responseString isEqualToString:#""]) {
// reload
}
}
When your app is running, you can register to receive push notifications. Then it's simply a matter of implementing the method, making it update your tableview.
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
It's pretty well documented by Apple.