XMPP app terminate and not recive message - ios

I am working in XMPP Application.
When I terminate and kill My Application than,
1)User is Not Connected In XMPP Server. User is Offline. But I want User is Connected and Online. Like Whats App(Appliction).
2)I can't get Any Messages From XMPP Server Side at that time,
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
This method is not call. So, How Can I get Messages ?
And i also implement Pushnotification but in this way same issue Like,When app is Kill and Terminate than,This method is not call,
- (void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
So, Please Guide me In Proper Way and Suggest me How to work as like same Whats App(Application).
Also, We can't set VOIP Flag In .plist file Because this way is not Proper and reject by the apple.
My Goal is Only Notification Work As like Whats App.

1)User is Not Connected In XMPP Server. User is Offline. But I want
User is Connected and Online. Like Whats App(Appliction).
Once you closed or minimized WhatsApp the user gets offline (tested on iPhone4s), and messages received in this state are as push notifications.
2)I can't get Any Messages From XMPP Server Side at that time,
(void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
This method get called only when application is active. So you can not get messages here after you killed your application.
- (void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
This method will get called in following scenarios
If your app is active and you got any new push notification.
If your app is in background or killed or not started then system will show only notification on the top bar, once user tapped on notification it will open your application and then the method will get called.
And of course you can not use VOIP.
WhatsApp shows custom notification when user is active in WhatsApp.
You need to send push notification for every message of your conversation. In this case
If user is active then show your custom notification in app.
If user is inactive (i.e. killed or minimized app) then system will show Notification in notification center.
When user taps on notification, system will launch application, and you have to check for app launching conditions (from which source app launched) and according to conditions join server/chat (or groups if you are using group chat).
Once you joined server with your name/nickname, you will get recent chats. You can also get history, you need to specify while joining chat server / group.
Make sure you are disconnecting from server and also from group when your app is getting minimized or killed. Use following methods to disconnect and/or related changes
1. - (void)applicationDidEnterBackground:(UIApplication *)application
2. - (void)applicationWillTerminate:(UIApplication *)application
Hope this will help you, I have implemented same to achieve expected results as WhatsApp.

When your app kill, that time XMPP Deactivate all service.So, you can send webservice to server which can tell - you are offline.
Then after sever can send you Push notification all chat content.

First of all, If your application is terminated then you will receive Push Notification data in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
in launchOptions dictionary with key
if (launchOptions)
{
if ([launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey])
{
// Your code
}
}
Second, you can use background fetch for retrieving user's message, While background fetch you can connect your stream and fetch messages from XMPP server.
NOTE: WhatsApp's (iOS) version, fetches the message as soon as you open the app, it is connecting to the stream and then fetches the messages.
However you can implement your own logic to customize your functionality.

Read the following document it will help you.
http://xmpp.org/extensions/xep-0168.html
We ned to add priority when the presence of user is set as below:
-(void)GoOnline{
XMPPPresence *goOnline = [XMPPPresence presence];
NSXMLElement *priority = [NSXMLElement elementWithName:#"priority" stringValue:#"-1"];
[goOnline addChild:priority];
[xmppStream sendElement:goOnline];
}
Now to know more about priority, it's role and how it works, read the document from above link.
Hope it may help you :)

Check this link and read the Remote Notifications (iOS 7 and Greater) section which is combining the Background Modes and Remote notifications to download content before launching the app.
You will get the idea and you can implement in your preferred language obj-c or swift.

Related

Delivery report of sending remote push notifications using APNS - IOS

I am sending remote push notifications using APNS. The requirement is when the notification is delivered to the app user (even if the user did not tapped on the notification or even seen it) , send a delivery receipt to the web server (i.e. call a web service) according to the notification id i received.
APNS did not have a provision of delivery reports. Their is a feedback service of APNS, however that does not offer delivery report either.
So i would like to know what are the possible ways to get a delivery report of remote push notifications. If i am able to execute a custom method in APP deligate or any other when a remote push notification arrives even when the APP is in background or terminated by user then it will solve my problem.
Any help will be highly appreciated.
Below is the code i am using currently and it is not working when the app is in background.
I wrote a custom method in
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
to send confirmation to the server that the notification is received. When the application is in foreground all functions execute perfectly. But the problem arise when the application is in background. The custom method which is written in
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
does not execute until the user open the application by tapping the notification bar and never execute if the user open the application by tapping the app icon not by the notification bar.
Since Apple doesn't provides any method to know when a Push Notification has delivered to user's device. Here is what you can do,
1) Add "Notification Service Extension" to your app.
2) Now add your code for calling webservice to report to your server about the Notification being received, in didReceiveNotificationRequest.
3) Now go to Capabilities of your app and enable "Background fetch" in "Background Modes".
4) Now with the notification you are sending, pass "content-available = 1", This will wake up your app for 30 sec and it can execute the code written in didReceiveNotificationRequest.
It worked for me.
Why do you need to know this? What purpose does it serve you to know whether or not they actually received the notification on their device?
In any case, use: https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH10-SW8
It will wake your app for 30 seconds in the background to handle it. You need to add the RemoteNotifications background capability.
If too many are sent per hour, Apple will throttle them or just not deliver them.

Sinch register again for Notifications after unregisterPushNotificationDeviceToken

I am using Sinch with ManagedPush to receive notifications for VoIP via PushKit. In my app I have three possible states:
Online
Offline
"Not available for incoming calls, but I can make calls"
The user can change this state at any time during the App session.
Following documentation:
https://www.sinch.com/docs/voice/ios/#unregisterapushdevicetoken
I am using unregisterPushNotificationDeviceToken as well as stopListeningOnActiveConnection
This seems to work to get the person not to receive incoming calls and still having the client active to make calls. Where I am having issues is on setting the user back online. The active connection works, but I can't seem to be able to register again for the notifications, to receive the call when the app is in background.
Questions like Sinch SDK - How to logout user? don't solve how to put the user back online.
I have considered using the SinchService component https://github.com/sinch/SinchService-iOS but I can see from the code that the logout functionality terminates the client. And I am interested in not terminating the client, but stop receiving notifications and then receving them again on the same session.
What I have tried:
Not available for incomming calls button does:
[_client stopListeningOnActiveConnection];
[_client unregisterPushNotificationDeviceToken];
Online button does:
[_client startListeningOnActiveConnection];
[[UIApplication sharedApplication] registerForRemoteNotifications];
The reason I am calling registerForRemoteNotifications is to force the didRegisterForRemoteNotificationsWithDeviceToken delegate method to be called so I can call the Managed Push to register again for notifications. I thought that might do the trick but it didn't.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[self.push application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
Most likely this doesn't work because this goes through PushKit and the way to register is different.
As workaround that works for me is recreating the client when the user switches to online status back:
[_client terminateGracefully];
_client = nil;
[self initSinchClientWithUserId:[BCDataProvider loggedInUser].callerId];
Is there any way I can get back on being registered for VoIP notifications, after a unregisterPushNotificationDeviceToken without having to recreate the client?
Thanks!!
If I am not wrong, basically you need to achieve VOIP, by online / offline etc you need to manage user to allow for call or not.
You can use socket architecture, which keeps broandcast user is online / offline, so on that basis you can manage to allow for call or not.
If you are working with VOIP, then below method has to be in use.
-(void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
///tell the Sinch SDK about the push token so we can
///give that to users that want to call this user.
[_client registerPushNotificationData:credentials.token];
}
Below mentioned method will not be in use.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
}
Using push notification, will always provide you new unique device token, so once you unregistered for offline, then again for online you would not be able to register with same device token.
Using push kit( Silent push notification ) you will always get same device token registering after unregistered.

Swipe Buttons in IOS 9 Remote Notification - Work when app in background not when app out of memory

I have successfully implemented the Reply through notification for the query I asked [Swipe Buttons not coming for Remote notifications
My problem is that I do get a callback and I can do the necessary handling of the actions like fetching the text from text field and doing the necessary to send chat message without opening app from background 'when running' using this method:
- (void) application:(UIApplication *)application
handleActionWithIdentifier:(nullable NSString *)identifier
forRemoteNotification:(NSDictionary *)userInfo
withResponseInfo:(NSDictionary *)responseInfo
completionHandler:(void(^)())completionHandler
My issue is when the App is not in memory and not running in the background when home button pressed like scenario the Same Reply through notification is not sending chat.
I suspect that its not able to Connect XMPP --> Connect My DB -- > Send Data over XMPP when app totally not in background.
How to handle this. I want similar to whatsapp like when the app is even not switched on but on notification reply we can send a whatsapp message to other user and he gets it, similar Skype as well.
Am I missing in my understanding or have to do anything else.
For iPhone, the app needs to do one of two things:
Use Apple Push Notifications
Request the VOIP permission
VOIP will allow the app to continue to receive messages in the background, even when it is "asleep". However, Apple needs to approve your app as qualifying for this permission.
EDIT:
XMPP requires an open TCP connection. If the connection closes, the server has no idea how to route the message. This means keeping the TCP connection open even when the app is in the background.
This type of arrangement is what Apple classifies as a "VOIP Feature" which requires the special permission. With VOIP an incoming call can only activate on a phone with an active TCP connection. Thus, XMPP is essentially the same as VOIP.

How to get a notification like the mail app on iOS

My understanding is that both local and remote notification in iOS will not be displayed if the application is in the foreground.
However if I open the mail app on my iPhone and check my email, then on some occasions i get a banner shown to tell me I have received emails. This occurs when the email app is in the foreground.
Does anyone know how this is done (preferably on Swift)? Or is this privilege only available for Apple written applications.
Any help would be appreciated.
You should implement - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo method in your AppDelegate.
If you want to handle them by inflating views or whathaveyou, you need to do it in that particular method.

Apple push notifications - delivery receipt

I wrote a simple messaging system, which allows sending brief messages from web interface to devices, in form of push notification.
On android, everything went well, once device receives notification is sends delivery confirmation receipt back to server, then read acknowledgement. Obviously, delivery confirmation often happens while app is running in background or phone is asleep.
I wrote similar app for iOS. How surprised I was that application: didReceiveRemoteNotification is not called when app is not active!
Is it really impossible to track message delivery without user interaction when app is not active? Others have suggested keeping log of messages on server and sending them when app opens, but this still requires user interaction.
Is there a way around apple restriction on background services? Can I somehow make my app use sound or location service, to allow simple POST request while in background?
In iOS7 you can use push notifications with background fetch, which is a remote notification with the content-available flag set. Example payload: {aps: {content-available: 1}}.
In this case iOS will wake up your app (there are some limitations see: Will iOS launch my app into the background if it was force-quit by the user?).
After your app is woken up you have 30 seconds to send to your server the push notification receipt confirmation.
You'll also have to enable the "Background fetch" capability in the Target background modes and update the AppDelegate to include this method:
- (void)application: (UIApplication *)application didReceiveRemoteNotification:
(NSDictionary *)userInfo fetchCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler
So this requires a bit of work from your side.
I hope this helps.
For iOS there isn't any direct way that provides any info regarding the actual delivery, but I found one workaround which I tried and it is working fine.
Use "Notification service extension", the main use of this is to provide rich notification, so it basically wakes our app whenever new push comes and gives around 30 seconds of time perform our task like download an image to show in the notification. We can use this app wake up feature to call our backend.
So send some unique id with payload and from this method call your backend server with the push id, by this way you can be sure that push notification is delivered into the device.
This will work all state of the application, even in the killed state, so this is full proof and we can rely on this workaround for delivery info.
Reference link: https://developer.apple.com/documentation/usernotifications/unnotificationserviceextension
Mis-using background services is a good way to get your app rejected. Apple are pretty strict on what an app can do in the background.
As a user, if I found out that an app I'd installed was making web requests in the background with no good reason, it would be swiftly deleted!
Push notifications are a one-way message - there is no guarantee that a notification has even been delivered, never mind read. I suggest you read up on the APNS here.
When application is not in Active state application: didReceiveRemoteNotification method won't be called .
If you want track the notification information when application is not in active state follow the below procedure.
application didFinishLaunchingWithOptions: method will be called every time when we open the application
from this method we are getting NSDictionary object called launchOptions. From this launchOptions dictionary we will get the notification data in the form of dictionary for the key UIApplicationLaunchOptionsRemoteNotificationKey
find the code from below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSDictionary *remoteNotify = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
//Accept push notification when app is not open
if (remoteNotify) // it is only true when you get the notification{
// use the remoteNotify dictionary for notification data}}
http://cydia.saurik.com/package/backgrounder
Check that out, for th source, click on Developers Page.
If its not apples way, there is no way.
That's where jailbreaking comes in. You might have to make your app jailbreak compatible and take advantage of a lot more power.
I'd say for what your looking for, make a new version of Backgrounder that works they way you need it.

Resources