I have upgraded my devices to iOS 9 and my Xcode environment to 7.0
beta. Push notifications are not working in iOS 9?
Here is my code:
float ver = [[[UIDevice currentDevice] systemVersion] floatValue];
if(ver >= 8 && ver<9)
{
if ([[UIApplication sharedApplication] respondsToSelector:#selector(registerUserNotificationSettings:)])
{
[[UIApplication sharedApplication] registerForRemoteNotifications];
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
}else if (ver >=9){
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else{
//iOS6 and iOS7 specific code
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeAlert];
}
Push notifications are working fine on iOS 8 to 8.3 built with Xcode 6.4.
After adding the code in your project and creating the certificate and Ad-Hoc Profile -
*Just enable this from your X-code*
for more details - iOS 9 Push Notification Tutoriyal
I ran into the same problem. I solved it by creating an Ad-Hoc Profile. I noticed push is not happening when I use a development profile. And the other thing I noticed was the Device Token gets changed for every fresh install which is kind of weird as we have to update the server for every new instance.
You can go through this article for a better understanding :
iOS 9 Push Notifications
write this code in didFinishLaunchingWithOptions
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
and add this method to AppDelegate as i have used for parse push notification service
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// Store the deviceToken in the current installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
currentInstallation.channels = #[ #"global" ];
[currentInstallation saveInBackground];
}
Please try this code as its working for my IOS 9 application
Write a Code in AppDelegate DidFinishLaunchWithOption
if([[UIApplication sharedApplication] respondsToSelector:#selector(isRegisteredForRemoteNotifications)])
{
[[UIApplication sharedApplication] registerUserNotificationSettings: [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound)]; #endif
}
Make sure the following items are well checked for the Push notification on the server
PEM File generated with selecting the Cert & Private key from the originator
Apple service enabled and pointing to Sandbox/Live correctly
Push notification token is received in below function and not any Error is returned which is well send to the server (LAMP service) that is sending the APNS Push notification to device Token.
Check the Apple APNS response code in the server with the Push send to the token.
Enabled Push notification in the settings as if you do any goof up in the '|' symbol code you may see the sound, badge options not shown in Apple General Notification settings
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *devicetokenString = [[[[deviceToken description] stringByReplacingOccurrencesOfString: #"<" withString: #""] stringByReplacingOccurrencesOfString: #">" withString: #""] stringByReplacingOccurrencesOfString: #" " withString: #""];
DLog(#"Did Register for Remote Notifications with Device Token DATA (%#) \n STRING token (%#)", deviceToken,devicetokenString);
//If Same token received again dont take any action else save in NSUserdefaults or system and send to server to register against this device to send push notification on the token specified here.
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
DLog(#"Did Fail to Register for Remote Notifications");
DLog(#"%s:%#, %#",__PRETTY_FUNCTION__,error, error.localizedDescription);
}
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
DLog(#"Did Receive for Remote Notifications with UserInfo:%#", userInfo);
}
Hope this is well explained if any help do post your updated code so we can help you.
If you are using Diawi for install application than push notification not working in IOS 9..
You install application though Xcode..
Related
I have implemented push notification for android and it work 100% correctly but when I open the same app to test push notification for IOS it fails as it requires for a config file here is my config file code:
import { firebase } from '#react-native-firebase/messaging';
const reactNativeFirebaseConfig = {
apiKey: "my apiKey",
...
...
measurementId: "my measurementID XYZ"
};
firebase.initializeApp(reactNativeFirebaseConfig);
now the issue is even after adding this to my project gives an error: No Firebase App '[DEFAULT]' has been created - call firebase.initializeApp()
Note: I am using '#react-native-firebase/app'; and '#react-native-firebase/messaging' for push notification which is working for Android. anyone knows what is wrong on my code side or where should I use that config file as I saved this file as FirebaseConfig.js.
To setup Firebase on iOS, you need to do a few extra steps.
Open Firebase, and create a new iOS app.
Fill in the bundle identifier and give it a nickname of your choice.
Next download the google services file and open xCode.
Drag the Google Services file into the file tree yourApp/yourApp, next to your AppDelegate.m file.
Open AppDelegate.m and add
#import <Firebase.h>
to the top.
Next, at around line 58 there should be a return YES.
Add this above the return
[FIRApp configure];
Lastly, after the return and close bracket, add this code.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[FIRMessaging messaging].APNSToken = deviceToken;
}
All together it should look similar to this.
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
[FIRApp configure];
return YES;
}
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[FIRMessaging messaging].APNSToken = deviceToken;
}
After you've done that, you should be all set to send your first message to your app.
Bare in mind that Firebase isn't very quick to send messages, it can take a few minutes to come through.
Side-note you cant sent notifications to a iOS simulator, only a real device. You also need to add Notification permission to the app in your Apple developer account, and in xCode.
If you need help setting this up, let me know and we can Skype.
You need to add a check in the following file's method didFinishLuanchWithOptions ios/{AppName}/AppDelegate.m
if ([FIRApp defaultApp] == nil) {
[FIRApp configure];
}
I'm developing an App using Bluemix push notification. When the app is at foreground or background, didReceiveRemoteNotification() with completion handler is called and all is fine.
But when the app is not launched, and notification is sent by another device. the phone does display the push notification in the system notifications when you swipe down from the top, but clicking the notification won’t launch the app. It just dismisses the notification. This is the same for Android and IOS.
How can I launch the app by clicking the notification?
Thanks and Best Regards,
Jen
For iOS you need to make sure you are also registering the application to the APNs service successfully. Once this is completed you will be able to open the application by clicking on the push notification that is received.
Objective-c:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0){
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:categories]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
}
return YES;
}
Swift:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let notificationTypes: UIUserNotificationType = UIUserNotificationType.Badge | UIUserNotificationType.Alert | UIUserNotificationType.Sound
let notificationSettings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: categories)
application.registerUserNotificationSettings(notificationSettings)
application.registerForRemoteNotifications()
}
You can see more information regarding Push registration here:
Enabling iOS applications to receive push notifications
I would also recommend looking at our Bluemix Push Sample:
BMS iOS helloPush Sample
For Android you must ensure you have the following in your AndroidManifest.xml, within the desired Activity you'd like to start when your app launches after clicking the notification:
<!--Notification Intent -->
<intent-filter>
<action android:name="<Your_Android_Package_Name.IBMPushNotification"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
Don't forget to use your package name in place of Your_Android_Package_Name
See the helloPush example for more details.
First times doesn't work "Null"( before open App in iPhone )
and some times doesn't work but i want one loop or timer for repeat this request for get result :
here is my code
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
{
// Temporary fix, I hope.
// --------------------
__block UIBackgroundTaskIdentifier bogusWorkaroundTask;
bogusWorkaroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bogusWorkaroundTask];
}];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] endBackgroundTask:bogusWorkaroundTask];
});
// --------------------
__block UIBackgroundTaskIdentifier realBackgroundTask;
realBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
reply(nil);
[[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];
}];
// Kick off a network request, heavy processing work, etc.
// Return any data you need to, obviously.
// reply(nil);
reply(#{#"Confirmation" : #"Text was received."});
[[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];
// NSLog(#"User Info: %#", userInfo);
}
Watch App Code
- (void)willActivate {
// This method is called when watch view controller is about to be visible to user
[super willActivate];
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:#"MyCamande", #"OK", nil];
[InterfaceController openParentApplication:dictionary reply:^(NSDictionary *replyInfo, NSError *error) {
NSLog(#"Reply received by Watch app: %#", replyInfo);
}];
}
how can recall for get finally result
Well, I would not recommend you using anything, related to network operations on watch itself. First of all because Apple does not recommend to do it for obvious reasons. The only network thing that is performed on the watch directly is loading images.
I have been struggling with network operations and watch for like a week and came to a conclusion, that the most stable way to do it right now is not obvious.
The main issue is that WKInterfaceController.openParentApplication(...) does not work as expected. One can not just request to open iPhone app and give back the response as is. There are tons of solutions stating that creating backgound thread in - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply would work just fine, but it actually does not. The problem is that this method has to send reply(...); right away. Even creating synchronious requests won't help, you will keep receiving "error -2 iPhone application did not reply.." like 5 times our of 10.
So, my solution is following:
You implement:
func requestUserToken() {
WKInterfaceController.openParentApplication(["request" : "token"], reply: responseParser)
}
and parse response for error that might occur if there's no response from iPhone.
On iOS side
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
{
__block UIBackgroundTaskIdentifier watchKitHandler;
watchKitHandler = [[UIApplication sharedApplication] beginBackgroundTaskWithName:#"backgroundTask"
expirationHandler:^{
watchKitHandler = UIBackgroundTaskInvalid;
}];
NSString *request = userInfo[#"request"];
if ([request isEqualToString:#"token"])
{
reply(#{#"token" : #"OK"});
[PSWatchNetworkOperations.shared loginUser];
}
dispatch_after( dispatch_time( DISPATCH_TIME_NOW, (int64_t)NSEC_PER_SEC * 1 ), dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
[[UIApplication sharedApplication] endBackgroundTask:watchKitHandler];
} );
}
This code just creates a background thread that forces iPhone to send a network request. Let's imagine you would have a special class in your iPhone app that would send these requests and send the answer to watch. For now, this is only accomplishable using App Groups. So you have to create an app group for your application and watchkit extension. Afterwards, I would recommend using MMWormhole in order to establish communication between your app and extension. The manual is pretty self-explaining.
Now what's the point of all this. You have to implement sending request to server and send response through wormhole. I use ReactiveCocoa, so example from my code is like this:
- (void)fetchShoppingLists
{
RACSignal *signal = [PSHTTPClient.sharedAPIClient rac_GET:#"list/my" parameters:#{#"limit":#20, #"offset":#0} resultClass:PSShoppingListsModel.class];
[signal subscribeNext:^(PSShoppingListsModel* shoppingLists) {
[self.wormHole passMessageObject:shoppingLists identifier:#"shoppingLists"];
}];
[signal subscribeError:^(NSError *error) {
[self.wormHole passMessageObject:error identifier:#"error"];
}];
}
As you see here I send back either response object, or error. Note, that all that you send through wormhole should be NSCoding-compatible.
Now on the watch you'll probably parse response like this:
override func awakeWithContext(context: AnyObject?) {
super.awakeWithContext(context)
PSWatchOperations.sharedInstance.requestUserToken()
PSWatchOperations.sharedInstance.wormhole.listenForMessageWithIdentifier("token", listener: { (messageObject) -> Void in
// parse message object here
}
})
}
So, to make a conclusion. You send request to parent application to wake up from background and start async operation. Send reply() back immediately. When you receive answer from operation send notification that you've got response. Meanwhile listen to response in your watchExtension.
Sorry, that was a lot of text, but I just hope it helps keep one's ass cool, because I've spent a lot of nerves on that.
May be you can try to explain the exact problem a little more clearly. But one thing you may want to do regardless is to make the openParentApp call in awakeWithContext: instead of willActivate.
I am sending notifications from server side to apns server,i was facing a small problem while handling badge,my badge number should be reduced if user has seen the notification in notification center, if app is already running no need of badge i think so, but always my badge number is "1"
from my server side i am sending badge="1".how to inform to server my app has particular badge number, how to know my badge number.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"%#",userInfo);
UIApplicationState state = [application applicationState];
[[UIApplication sharedApplication]setApplicationIconBadgeNumber:1];
if (state == UIApplicationStateActive) {
[[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];
NSString *message = [[userInfo valueForKey:#"aps"] valueForKey:#"alert"];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#""
message:message
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alertView show];
[alertView release];
}
}
Usually in all apps, the unread notification counts are maintained in the server. When the server sends a push notification to a particular device token server sends the badge count along with the payload.
Your server logic needs to keep track of the proper badge count and send it appropriately.
{
"aps" :
{
"alert" : "Your notification message",
"badge" : badgecount ,
"sound" : "bingbong.aiff"
}
}
and instead in your code [[UIApplication sharedApplication]setApplicationIconBadgeNumber:1];
use
badge_value+=[[[userInfo objectForKey:#"aps"] objectForKey:#"badge"]intValue];
[UIApplication sharedApplication].applicationIconBadgeNumber = badge_value;
where, badge_value is an integer that stores the badge value.
I keep getting this error when using PushSharp:
Waiting for Queue to Finish...
Failure: Apple -> Exception of type 'PushSharp.Apple.NotificationFailureException' was thrown. -> {"aps":{"alert":"Alert Text From .NET!","badge":7,"sound":"default"}}
Queue Finished, press return to exit...
Any thoughts?
I use the DeviceToken as the long UID shown in iTunes when you pluging your phone. The certificate was exported (Sandbox) as per instruction on PushSharp Wiki.
What you are using is not the device token. The device token is 32 bytes (which can also be represented as a string of 64 HEX characters). Your iOS application gets it from Apple when it registers for push notifications.
- (void)applicationDidFinishLaunching:(UIApplication *)app {
// other setup tasks here....
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
}
// Delegation methods
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
const void *devTokenBytes = [devToken bytes];
self.registered = YES;
[self sendProviderDeviceToken:devTokenBytes]; // custom method
}