Can I get badge number with trigger.io - trigger.io

Trigger.io provides a forge.notification.setBadgeNumber method to set the ios badge number. Is it possible to retrieve the badge number with trigger.io?
My use case is that I have a messaging system where the badge number is the number of unread message - I want to decrease the badge number when the user reads a message. To do that, I need to know the current badge number...
Suggestion on better ways to implement this will also be appreciated.

You could easily write your own native module to get the current badge count in Trigger.io apps. I have one in use and the relevant function looks like this:
+ (void)getBadgeNumber:(ForgeTask*)task {
NSNumber *count = [NSNumber numberWithInt:[[UIApplication sharedApplication] applicationIconBadgeNumber]];
[task success:count];
}
UPDATE:
It seems like Trigger.io added the getBadgeNumber call to their notifications module. Available methods are:
forge.notification.setBadgeNumber(number, success, error)
forge.notification.getBadgeNumber(success, error)
If you're using the Parse module for push notifications you can even retrieve and set the badge number on the Parse server as of now.

Related

iOS, CloudKit - do I need to do a fetch when my app starts?

I'm setting up registrations for notifications of iCloud changes.
Say a new device is added to the icloud account, I'm just wondering how that device will get the private database records.
Do I need to do a one off query?
I'm hoping that notifications will be used at all other times.
Let's start with some relevant characteristics of subscription notifications:
First: Subscription Notifications are specific to a user + device pair. If I install you app on my phone, I start getting notifications. I won't get the notifications on another device until I install the app there, too.
Second: Notifications are unreliable. Apple docs are quite clear that they do not guarantee delivery. When you receive a notification, there could have been several prior notifications. Thus, Apple offer's two mechanisms to track which notifications you've seen:
Read/unread status: you can mark notifs as read. Apple's docs contradict themselves about what this actually does. This page says
If you mark one or more notifications as read using a CKMarkNotificationsReadOperation object, those notifications are not returned, even if you specify nil for previousServerChangeToken.
However, this isn't true. The fetch operation clearly returns both read and unread notifications. WWDC 2014 Video 231 (Advanced Cloudkit) contradicts the documentation page, explaining that unread tokens are always returned as well as read tokens so multiple devices can sync up. The video gives a specific example that shows the benefits of this behavior. This behavior is also documented on SO: CKFetchNotificationChangesOperation returning old notifications
change token: each fetch operation will return a change token that you can cache. If you pass the token to a fetch, the fetch will only return tokens from that point, whether read or unread.
At first glance, it would seem that Apple is providing for the behavior you want: install the app on one device, start processing notifications, install the app on a second device, and fetch all those prior notifications in order to catch up.
Unfortunately, as I've documented in CKFetchNotificationChangesOperation: why are READ notifications all nil?, any time I fetch notifications, the ones previously marked as "read" all have nil contents. All the info in the read notifications is lost.
In my scenario, I chose to:
Always fetch the latest record(s) at startup
Fetch notifications using the previously saved change token (if it exists)
Process the new notifications
Mark the notifications as read
save the latest change token for use on the next fetch
For your scenario, you could try:
Fetch notifications using the previously saved change token (if it exists)
process the notifications (DO NOT MARK THEM AS READ)
save the latest change token for use on the next fetch
Your first device will ignore old notifications on each subsequent fetch because you're starting each fetch from the change token point. Your second device will start with a nil change token on the first execution, and thus pick up all of the old notifications.
One word of caution: even though aforementioned WWDC video clearly says Apple keeps all the old notifications, I have found no documentation that says how long they hold this info. It may be forever, it may not.
updated with notification fetch example
Here's how I'm fetching notifications, marking them read, and caching the change token:
#property CKServerChangeToken *notificationServerChangeToken;
Then...
-(void)checkForUnreadNotifications
{
//check for unread cloudkit messages
CKFetchNotificationChangesOperation *op = [[CKFetchNotificationChangesOperation alloc] initWithPreviousServerChangeToken:_notificationServerChangeToken];
op.notificationChangedBlock = ^(CKNotification *notification)
{
//this fires for each received notification. Take action as needed.
};
//maintain a pointer to the op. We will need to look at a property on the
//op from within the completion block. Use __weak to prevent retain problems
__weak CKFetchNotificationChangesOperation *operationLocal = op;
op.fetchNotificationChangesCompletionBlock = ^(CKServerChangeToken *newServerChangeToken, NSError *opError)
{
//this fires once, at the end, after all notifications have been returned.
//this is where I mark the notifications as read, for example. I've
//omitted that step because it probably doesn't fit your scenario.
//update the change token so we know where we left off
[self setNotificationServerChangeToken:newServerChangeToken];
if (operationLocal.moreComing)
{
//more notifications are waiting, recursively keep reading
[self checkForUnreadNotifications];
return;
}
};
[[CKContainer defaultContainer] addOperation:op];
}
To set and retrieve the cached change token from the user defaults, I use the following two functions:
-(void)setNotificationServerChangeToken:(CKServerChangeToken *)newServerChangeToken
{
//update the change token so we know where we left off
_notificationServerChangeToken = newServerChangeToken;
NSData *encodedServerChangeToken = [NSKeyedArchiver archivedDataWithRootObject:newServerChangeToken];
NSUserDefaults *userSettings = [NSUserDefaults standardUserDefaults];
[userSettings setObject:encodedServerChangeToken forKey:UD_KEY_NOTIFICATION_TOKEN_CKSERVERCHANGETOKEN_PROD];
//Note, the development and production cloudkit environments have separate change tokens. Depending on your needs, you may need to save both.
}
and...
-(void)getNotificationServerChangeToken
{
NSUserDefaults *userSettings = [NSUserDefaults standardUserDefaults];
NSData *encodedServerChangeToken = [userSettings objectForKey:UD_KEY_NOTIFICATION_TOKEN_CKSERVERCHANGETOKEN_PROD];
_notificationServerChangeToken = [NSKeyedUnarchiver unarchiveObjectWithData:encodedServerChangeToken];
}

Cordova Push notifitication badge not displaying on app icon iOS

I am using cordova push plugin where I am getting notification and all data I needed, but also I want to set badge as per the unread notification or the number i am getting into count of push notification but I am not sure why I am not getting this count as a badge into app icon of iOS device
Here is the json format I am getting into push notification success function
{
"count":"1",
"sound":"default",
"additionalData":{
"foreground":true,
"product_id":"19",
"user_id":"2",
"coldstart":false,
"notificationstatus":"like"
},
"message":"Username likes your product"
}
Sound and message both were working perfect but not count.
Any suggestion ?
I noticed that, there is a string value of count in the response, and it was the mistake.
Count value must be an integer.
Hope this will help others too.
what you receiving is ok but one key is wrong. the key count should be badge. This is the problem i think. Try to change the key and reply the result.
reference - https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html

APNS Background handling for badge counter

I am integrated APNS in my app, The requirement is to maintain notification count when app in background. For example we got notification in background in there is key counter count , i,e changing dynamic in every notification, Can it possible to handle in iOS when app is background or app has forcefully closed.
This is the APNS payload from back end server.
{
"aps" : {
"alert" : "You got your emails.",
"badge" : 9,
"sound" : "bingbong.aiff"
},
"acme1" : "bar",
"acme2" : 42
}
The value for key badge is automatically considered as badge count.On ios app side no need to calculate or handle the count.
In above example 9 is the badge count.So your app icon will show 9.
NOTE While your app is close u can't handle badges on your own.Thats why we are using badge key from APNS Payload
For better clarification about notification see documentation
EDIT: if you want to reduce the badge count on your own.Decrement the count and update it yourself.as follows
NSInteger numberOfBadges = [UIApplication sharedApplication].applicationIconBadgeNumber
numberOfBadges -=1;
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:numberOfBadges];
or else make the count to 0, so that badge icon will be disappeared.Add the below code in ** applicationDidBecomeActive**
application.applicationIconBadgeNumber = 0;
For managing the notification counter you have to setup functionality at server. lets take Facebook example if you are not reading the new notification the counter keep increase by one and once you click on notification it comes back to zero. so whenever you read new notification it also managed on server side whether is user opened it or not.
lets say there are 3 notifications user di't see than for next one counter will be 4.
And once your receive the count from server with update, handle it like if all updates are viewed application badge counter set to 0
this is my understanding as i have implemented the same in my iOS application if anyone has any good solution. please suggest.
I hope this picture(source google) will give the complete understanding.

Is there a way to get updated badge counter from QuickBlox in iOS?

I'm successfully getting push notifications for chats which are send by QuickBlox it self. However there's certain cases where I'm sending push notifications to other users in code too. At this point, I lost my self in sea !
Another user who's currently logged-out, so the app is showing 5 in badge counter (for unread chats).. then if I send him a push via code it should increase to 6 ... but its not updating. How do I pass 6 in QBMPushMessageBadgeKey with push I'm sending in code.
Please help me in figuring this out !! This will gonna a big issue in QuickBlox.
For sending push notifications you can use
+ (QBRequest *)createEvent:(QBMEvent *)event successBlock:(void (^)(QBResponse *, NSArray *))successBlock
errorBlock:(QBRequestErrorBlock)errorBlock;
and the simplest way is to use:
+ (QBRequest *)sendPush:(QBMPushMessage *)pushMessage toUsers:(NSString *)usersIDs successBlock:(void(^)(QBResponse *response, QBMEvent *event))successBlock errorBlock:(void (^)(QBError *error))errorBlock

Send programmatically SMS on jailbreak device

I am using a iOS 6 iphone 4S and I want to be able to send the unnoticed sms messages.
So using the standard view controller won't work in this case.
I tried using
- (BOOL)sendSMSWithText:(id)arg1 serviceCenter:(id)arg2 toAddress:(id)arg3;
but it doesn't send anything and returns NO. I used nil for arg2.
Can someone suggest a way to do it on iOS 6?(for jailbroken devices)
Found out why - (BOOL)sendSMSWithText:(id)arg1 serviceCenter:(id)arg2 toAddress:(id)arg3; is not working since iOS 6.
This API is protected by the entitlement com.apple.CommCenter.Messages-send. Just sign your app with this entitlement set to true. It's much better than my another answer here (XPC method) because of the two main reasons:
sendSMSWithText tells you whethere message was sent successfully
Messages sent using sendSMSWithText are not being saved in the SMS database and can't be seen anywhere. On the other hand, messages sent using XPC method are being saved in SMS database and can be seen in Messages application.
So, win win. I strongly suggest dropping XPC method also because it's using pretty low level API that can change easily in new iOS version. sendSMSWithText can be found even in iOS 7 and I don't think it will be dropped any time soon.
UPDATE
In order to use this API on iOS 7 and above you need to add another entitlement with bool value set to true - com.apple.coretelephony.Identity.get.
Straight from ChatKit.framework
dispatch_queue_t queue = dispatch_queue_create("com.apple.chatkit.clientcomposeserver.xpc_connection_queue", DISPATCH_QUEUE_SERIAL);
xpc_connection_t connection = xpc_connection_create_mach_service("com.apple.chatkit.clientcomposeserver.xpc", queue, 0);
xpc_connection_set_event_handler(connection, ^(xpc_object_t){});
xpc_connection_resume(connection);
dispatch_release(queue);
xpc_object_t dictionary = xpc_dictionary_create(0, 0, 0);
xpc_dictionary_set_int64(dictionary, "message-type", 0);
NSData* recipients = [NSPropertyListSerialization dataWithPropertyList:[NSArray arrayWithObject:#"12212"] format:NSPropertyListBinaryFormat_v1_0 options:0 error:NULL];
xpc_dictionary_set_data(dictionary, "recipients", recipients.bytes, recipients.length);
xpc_dictionary_set_string(dictionary, "markup", "SMS text");
xpc_connection_send_message(connection, dictionary);
xpc_release(dictionary);
recipients holds serialized property list with array of phone numbers to which you want to send your SMS - 12212 is just an example of phone number. Instead of SMS text you should put actual SMS text. Unfortunately, I couldn't find a way to check whether SMS was sent successfully.
To send message using this code your application entitlements should have com.apple.messages.composeclient key with boolean value set to true. Otherwise you get error in console saying application lacks entitlement.

Resources