PushSharp notification error - push-notification

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
}

Related

Push notifications are not working in iOS 9

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..

Watchkit , openParentApplication with WatchKit Extension

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.

Android GCM push notification shows every day

We have a pretty big issue in our app which is set up to receive GCM push notifications: Without launching a push notification, the app receives a push notification - this happens every day!
I've implemented a GCM Client (and obviously the Server side too) pretty much exactly as stipulated here: http://developer.android.com/google/gcm/client.html and here http://developer.android.com/google/gcm/client.html#sample-receive
Here is my onHandleIntent function in my GCMIntentService:
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) { // has effect of unparcelling Bundle
// If it's a regular GCM message (and the user is logged in), do some work.
if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType) && prefsMan.getLoggedIn(this)) {
// Post notification of received message.
sendNotification(extras.getString("message"));
Log.i(TAG, "Received: " + extras.toString());
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
What is causing the push notification from appearing every day, without it being launched from the server side?
Just as a side note, if I could set a bounty on this today already, I would do it, so please - any help will be appreciated, and I'll eventually give some of my rep to anyone who can help me with this issue, as soon as I'm allowed to do this on SO (two days from now).

Worklight 6.2 - Broadcast notification not being sent

We are trying to run the sample app for push notifications with some modification to get it to send out a broadcast notification, but it is not getting sent.
We have modified the PushBackendEmulator code as well. The emulator invokes the submitBroadCastNotification procedure successfully and the following result is returned:
Server response :: /-secure-{"result":"Notification sent to all
users","isSuccessful":true}/
However, it appears the WL.Server.sendMessage method is not sending the message and returns. I am not able to see the server side logs either after a thorough search on the liberty server except for the messages.log on the liberty server which shows the following when WL.Server.sendMessage is called.
ht.integration.js.JavaScriptIntegrationLibraryImplementation E
FWLSE0227E: Failed to send notification. Reason: FPWSE0009E: Internal
server error. No devices found [project worklight]
Here is the adapter code:
function submitBroadcastNotification( notificationText) {
var notification = {};
notification.message = {};
notification.message.alert = notificationText;
//notification.target = {};
//notification.target.tagNames = ['test'];
WL.Logger.debug("broadcast: " + notification.message.alert );
var delayTimeOut = **WL.Server.sendMessage**("PushNotificationsApp", notification);
WL.Logger.debug("Return value from WL.Server.sendMessage :"+ delayTimeOut);
return {
result : "Notification sent to all users"
};
}
Here is the PushBackendEmulator code:
public static void main(String [] args){
String serverUrl =
"http://208.124.245.78:9080/worklight";
String notificationText = "Hellofrombroadcastingnotifications";
String userId = "admin";
notificationText = notificationText.replace(" ", "%20");
Logger.debug("sending broadcast notification: " + notificationText);
URL url = new URL(serverUrl
+ "/invoke?
adapter=PushAdapter&procedure=submitBroadcastNotification&parameters=['" + userId + "','" + notificationText + "']");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(10000);
connection.setDoOutput(true);
Logger.debug("Connected to server");
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = "";
String inputLine;
while ((inputLine = in.readLine()) != null)
response+= inputLine;
Logger.debug("response is:"+ response);
in.close();
Logger.debug("Server response :: " + response);
connection.disconnect();
Looking at your application from the PMR, it seems to me like you have mixed both event source-based notifications and broadcast notifications.
If you want to use Broadcast notifications, this means you cannot try imposing sending the notification to any specific userId, etc as it is not needed nor based on userIds.
By default, all devices are auto-subscribed to a tag called "push.ALL".
You can read more about broadcast notifications API methods in the IBM Worklight Knowledge Center.
This is a modified version of your application, tested in iOS and Android: https://www.dropbox.com/s/l2yk2pbvykrzfoh/broadcastNotificationsTest.zip?dl=0
Basically, I stripped away from it anything not related to broadcast notifications:
I removed the push securitytest from application-descriptor.xml
I removed any function from the adapter XML and JS files and main.js file that is related to event source-based notifications.
The end result is that after the app is loaded, you are right inside the application (no login).
I then right-clicked the adapter folder in Studio > invoke procedure, and selected the submitBroadcastNotification option to send the notification ("aaa").
In the device, a notification was received. Tapping it (if the app is closed) launches the application, which then triggers the WL.Client.Push.onMessage API in common\js\main.js to display alerts containing the payload and props of the received notification.
This was tested in both iOS and Android.
As the application was loading, I could see in LogCat and Xcode console the token registration.
To test this in iOS, you will need to update application-descriptor.xml with your own pushSender password and add your own apns-certificatae-sandbox.p12 file.
To test in Android, make sure you are have generated a browser key in the GCM console and are using it in application-descriptor.xml
For both, make sure that all requires ports and addresses and accessible in your network

handling application badge number for my iphone app for apple push notification

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.

Resources