I'm trying to connect to our push server via MQTT-Client-Framework.
There is no complication for connecting to server and with a few line of code i can connect to server and subscribe to topic.
but I have a few question that I could not find any direct answer for them.
1) How can I keep my client running at background?
2) What happen after device restart? how can I automatically connect to server after device restart?
3)Suppose I got an error during connecting to server. Will this library trying to connect in a loop? how many times it try? or I need to manage this myself?
4) The same 3 scenario for subscribing to topic?
Based on my experience on MQTT-client framework following are the answers to your questions/queries. I hope it clarifies your concerns and helps you to move ahead.
1) How can I keep my client running at background?
You can not keep your MQTT client running in background, as Apple doesn't allow any application to keep running for long time in background. Though if you override its not guaranteed your application will keep running in background. You can read more about background execution support in apple documentation.
Also refer issue posted on github for given framework.
2) What happen after device restart? how can I automatically connect to server after device restart?
Each time your app begin execution you need to connect to your server using MQTT client framework there is no auto connect mechanism available in MQTT-client framework. I suggest to write init your connection in specific controller which executes immediately after your app launch except same as AppDelegate
3) Suppose I got an error during connecting to server. Will this library trying to connect in a loop? how many times it try? or I need to manage this myself?
If your MQTT-client fails to connect your server, you need to handle it yourself, library doesn't try to auto connect as mentioned in previous answer. I have written sample code as below. Use NSTimer for auto connect to server.
[self.mqttSession connectToHost:MQTT_HOST port:MQTT_PORT usingSSL:NO connectHandler:^(NSError *error)
{
if(error)
{
// Application fail to connect to server, write your code to auto connect here
}
}];
4) The same 3 scenario for subscribing to topic?
If your broker server has configuration to track your existing subscription for individual users/client then you don't need to subscribe each time.
Otherwise each time you need to subscribe to same topic on successful connection. Use following MQTTSessionDelegate method to subscribe.
- (void)connected:(MQTTSession *)session
Happy coding :)
1)Project->Capabilities->Background Modes. There has some options for allowing your app to run at background.
2)Generally speaking, MQTT will not be disconnected to the server if your app is allowed to run at background, but i think you would better check up the connection and maybe re-connect MQTT to your server when the app become active again.
AppDelegate-> - (void)applicationDidBecomeActive:(UIApplication *)application;
3)Unfortunately, yes, it will. And you have to manage yourself.
4)I can't help.
For your first question:
Details on how to run in the background on iOS can be found here. This link also lists the actions that Apple allows to run in the background, if your app does not meet those criteria then it is likely to get thrown out of the app store by Apple.
The list also shows which UIBackgroundModes to place in your Info.plist to flag that your app needs background access.
The other 3 I can't help with
We all know that Apple doesn't allow app service to run in the background, so MQTT will be disconnected in the background mode.
Now do one thing use better frameworks for MQTT like this in this framework you will get auto-reconnect and callbacks and many things.
So When you receive a call back that the MQTT is connected, immediately subscribe to all the topics that you have.
And if you want to get all missed messages then you need to change the MQTT configuration to like 'clean = false'.
Related
I'm developing an app in swift using this source https://github.com/aciidb0mb3r/SwiftMQTT
I want to add remote push notifications. I managed to do it with local notifications for example, when the app is running even if it's not in the foreground.
My question is how can i do it when the app isn't running. As i have seen when i close the app completed my broker say that i'm disconnected.
Is there any way to stay connected forever?
Something like remote push notifications that wake's up the application even if its not running
Thanks in advance :)
Finally I found out what it should be.
Hivemq (a mqtt broker) has a guide for developing a plugin with java, so that I did, I implemented push notification backend and with mysql connected clients and when the message comes I search offline clients with the topic of message and send only to them the push!
Thanks all for your help.
You can try using background fetch for periodical checking for messages.
Here is a useful tutorial for the different background modes ( it may be a bit outdated but the concepts are still valid ).
https://www.raywenderlich.com/143128/background-modes-tutorial-getting-started
I'm newbie in iOS App world so pardon me if my questions are simple and banals
I have this scenario:
my server side generates MQTT messages on a well known topic
my app can connect to the MQTT Topic and can receive messages
All works pretty good; what I would like to do now is the following (if possible)
When the user stops the app (by deleting it from the task manager) I'd like to have a kind of service able in being connected (or remaining connected) to the MQTT Topic; in this way also when the app is no more running I can receive MQTT messages
Basically I'd love to have something similar to Facebook messenger that is able in receiving messages also when the app is not running
NOTE: i can't use remote notification mechanism provide by Apple
Remote notifications would be perfect for this, shame that it's not an option for you.
There are a few other situations where apps can run periodically on the background, they are described here:
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
BUT, from that page: "In most cases, the system does not relaunch apps after they are force quit by the user."
So in general an app will run in background only if the user exits it normally, not if he forces it to quit in the task manager.
I have a chat application developed by JS. I want to send PING to server once in a while. Its not a problem if app runs on fore ground. The problem is when user minimizes it or open another app. My app looses its focus and gets into suspended state.
I have following two use-cases.
To keep the chat session open I need to send PING to server (Its an IRC server) every X minutes even the app runs in background.
We also need to check for new messages (by ajax on a local http server) and add a local notification to the notification queue so when user clicks on it app can resume
I have found apple does not allow running apps in the background. if they allow they require special permission. I found some apps does it by requesting finite length execution time.
What is the best way to get highest possible background execution time? As a chat app can I request permission for voip, location or any other way ?
Note: the app will be running in an environment where there is no Internet. Hence push notification will not work here.
Update: After doing a lot searching I found background fetch. It seem background fetch will suite it. But still the problem remains, its not called in a timely manner.
This sounds like an interesting problem. From reading the various comments, it sounds like you want this to work when you're on a local network - so you have wifi, but the wifi router/base station isn't connected to the actual internet?
Because background refresh isn't going to be predictable - you'll never know when it is going to update - you might want to get creative.
You could look into exploiting iOS VOIP support, only without the Voice! Apple has some tips on VOIP here. VOIP basically uses something called SIP (Session Initiation Protocol), which is signalling layer of the call, and a lot like HTTP. It's this SIP layer that you want to take advantage of.
This isn't going to be terribly easy, but it should be achievable. Setup your app to use VOIP, and then look into something like PJSip as your SIP library. Then, on your local network have a SIP Server (I'm sure there are plenty open source implementations) that you can register your iPhone against (so your server knows where your phone is, pretending to be a VOIP phone). This should work, because it doesn't need to go through Apple as far as I am aware... And will run happily on your local network.
Then, the server can send a message via SIP to the handset, as if it were instigating a VOIP session. You app is awoken, gets the messages - ideally from the SIP message if possible - and then just doesn't start the session. SIP was designed just for creating sessions, not just VOIP. When I worked in Telecoms R&D (a long time ago) we were using it to swap between Text/Voice/Video, all using local servers.
You'll have to jump a lot of hoops to make this work, but it would be pretty awesome. I have never tried this actual use case - especially with iOS, but I'm fairly sure it will work. It is a bit of a fudge, but should get you where you need to go.
Good luck!
You can use something like PubNub to build this chat app with iOS using native Objective-C code, or with the Phonegap (Cordova) libs.
The beauty with using a real-time messaging network like PubNub is that when the app goes to the background, you can easily have the chat messages come in on APNS.
When the app is in the foreground, it can just receive them as the native (PubNub) message. And if it needs to "catch-up" with the messages it missed while in the background (but received via APNS), its trivial to implement.
Also, PubNub is platform agnostic -- so you can easily also use it on Web, Android, BB, Windows Phone, etc.
http://www.pubnub.com/blog/build-real-time-chat-10-lines-code/
http://www.pubnub.com/blog/html5-websockets-beautiful-real-time-chat-on-mobile-using-pubnubs-channel-presence/
https://github.com/pubnub/objective-c/tree/master/iOS
https://github.com/pubnub/javascript/tree/master/phonegap
geremy
I have a project where I need to be able to send messages from a server running a web service to a specific iDevice. I have no idea how to do this, so any help is very appreciated.
The scenario: I have a web service which receives some message from an iDevice (could also be a Mac or PC, even an Android device). Depending on the content of this message I need to be able to send a message from the web service to another iDevice (I know the IP-address of the specific iDevice). I know how to use URLRequests to send a message from an iDevice to a server and collect the response from the server. In principle I could every 10 seconds send a request to the server asking if the server has any new messages to the sender (the iDevice sending the request), but I am pretty sure this is not the correct way to do it. Is there a way to have an iDevice listen for server communication on a specific port, so that the iDevice only does something active when it receives a message from the server to do something, e.g. display a message in the app listening for the server communication?
I guess I need to use something similar to the technology used for iMessage, but how is this done?
I am using XCode 4.6.2, iOS 6.1.
EDIT: Just to clarify my needs a bit more: The APNS seems to be TOO unreliable (at least that is what I have read in other threads regarding APN) as the web service in some cases can have the need for sending 2 distinct message to an iDevice within 1 minute (in some cases seconds), and as far as I have read in other threads this will simply not be possible because of how Apple's server handles ASPNS.
The app i am developing only needs to receive messages from the server when the app is active - is there any way, not using APNs, to do this, e.g. making the app listen for communication on a specific port?
Your scenario seems pretty similar to APPLE PUSH NOTIFICATIONs (APNs).
Ideally your server side should write a code in such a way that if there is any change on server side & need to be informed to all associated devices.
Then your server should post notification Apple server which will then send a notification to all the associated devices.
Refer this link
You already have but can use this code to identify the iOS/Mac deivce
NSString *identifierString = [[NSUserDefaults standardUserDefaults] objectForKey:#"myID"];
if (!identifierString) {
CFUUIDRef identifier = CFUUIDCreate(NULL);
identifierString = (NSString*)CFUUIDCreateString(NULL, identifier);
[[NSUserDefaults standardUserDefaults] setObject:identifierString forKey:#"myID"];
}
NSLog(#"%#",identifierString);
this code works till the lifetime of the app only.
After some search I have decided not to use the APNS, because it seems like people are having all sort of experience with it. I cannot use APNS because my project needs 100 % reliability and instant communication with the server.
I have decided to use tcp communication since my project only will be used in a local network. This will obviously mean more power consumption on the iDevices, but reliability is more crucial to the project.
I'm developping an app, that one one his tasks, is to send messages in tcp to a server. I want that the app continuos sending that tcp messages, even if the user quits the app.
I've that I could do that with:
"In your Info.plist set LSBackgroundOnly to 1."
But it don't work (I just tested on the simulator).
Thanks a lot for the help!
I'll just put Holex's comment into answer form to take care of this question. As he states, there are only 3 types of services allowed to run in the background of an application, location services, audio, and VoIP. A great read on what you can and cant do is the following http://developer.apple.com/library/ios/#DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html from Apple. Fairly detailed article of the structure of what happens when an application loses focus.
Alternatively however, if you don't plan on releasing through the app store, it is possible to fake a VoIP application and send/receive messages in the background. This is not a legitimate solution however, and really should be used for nothing other than if you need something quick, and extremely dirty.
iOS Voip Socket will not run in background That question, and any related ones are good places to start.