I've been able to set an application badge number to my iPhone app and updating it once the user interacts with my app:
[[UIApplication sharedApplication ] setApplicationIconBadgeNumber:currNrOfNotif];
What I wont though, is for this process to occur while in background mode, ie from within applicationDidEnterBackground or similar. I would like this process to be scheduled to run daily, every night at 00:00 00:00 and take the current number in setApplicationIconBadgeNumber and decrement it by -1. No need for push notifications (or any server kind) in other words as the only thing that will happen is a change of the badge number value.
First of all, how do I schedule an activity to occur while app's in background mode, without using remote server push notifications?
Secondly, how do I get or fetch the current application notification badge value and decrement it by one?
In this post, some people argue it simply can't be done even with local notifications and that server side push's required. One person, however, states it can be done by scheduling it by midnight. Who's right, and can someone please propose a solution to this?
Related
I’m using the onPause() method in my app so that users become ‘offline’ in my chat when the app is on pause. I found it very useful.
But the thing is that each time a user navigates between activities, the method is called for like a millisecond. This way, users are ‘online’ in activity A, ‘online’ in B, but ‘offline’ in between.
Because I use a green dot to described online users, it is very annoying since it changes to grey and then green again each time.
Is there a way to prevent this?
onPause is part of the Activity lifecycle, which relates to the different states an Activity goes through - it's not about whether your app as a whole is in the background. Here's what the docs say about it
The system calls this method as the first indication that the user
is leaving your activity (though it does not always mean the activity is being destroyed); it indicates that the activity is no longer in the foreground (though it may still be visible if the user is in multi-window mode).
There are a few ways you could handle it - the simplest would be to have a navigating flag you set when you're switching to activity B. Then the onPause can check that flag, and skip setting you to offline if there's a navigation even going on.
I'm assuming you mean the dot is flashing for other users (since you wouldn't be looking at the same View if you're the one switching between activities) - it might actually be a good idea to have the app send out an "I'm online" ping every so often anyway.
That way they can set a user to offline if they don't get a message after a certain amount of time - it just means that if a user gets a crash, their network drops or whatever, they don't look online the whole time just because they didn't send an "I'm offline now" message through onPause
I have built a react native app/game where a user has 30 mins to finish a task....when they start task, the 30 mins starts to countdown and it is registered in DB (Firebase) that user is "in play". When they complete task (or 30 mins run out) then DB is again updated to "not in play".
Countdown function is operating on phone and not on server.
Problem is that if the user exits the app, then the counter on the phone ceases (the user is no longer "in play") but the DB does not know about it.....there appears to be no "user has exited app" event/handler that I can use to let DB know that user has quit.
I was thinking maybe the countdown logic should be running on backend but I cant think how.....any ideas?
Currently there is no way to handle app terminated in React Native so I think your best shot is to implement it on the backend.
How about when the user starts, you save the time the user started, and if the time difference between now and when the countdown was started surpasses 30 minutes the user is no longer "in play".
One way to detect that the user has left the game would be with Firebase's onDisconnect handler. With this call you register a write operation on the database that is executed when the server detects that the client is gone.
The server can detect this in two ways:
If the client disconnects cleanly, it sends a message to the server that it is disconnecting and the server runs the disconnect handlers for that client straight away.
If the client disconnects in another way, the server will detect that the client is gone when the socket times out, which may take a few minutes.
So in your case you could use an onDisconnect handler to either remove the player from the game, or otherwise mark them as "gone".
The only problem with this approach is that dirty disconnects may take a few minutes, which might be too long for your scenario.
An alternative would be to have the client write a message into the database periodically to signify that it's still here, e.g. a lastUpdated timestamp.
You can then in any code that reads the data use that timestamp to detect if the player was still recently playing, and consider them "gone" after a certain period that works well for your game. This code can then remove the player from the database.
This code can run in a server-side component if you want, but I've in the past also run this type of code in the client and then used (server-side) security rules to ensure it can only remove users that are "gone".
I have created the application, which track the GPS Location of user at specific time period. This process is run 3 times in background. So, App need to keep alive in background.
To achieve the our requirement, we use the Location manager (GPS) running in the background. So, it will never been killed by OS. Also, we have run the background task thread while App is in background.
This approach working fine on iOS 6 and before and running more than 10 minute in background.
But in iOS 7 Application going to killed after 10 minute.
Please need suggestion for keep the Timer alive in background.
We would appreciate the earliest response. Thank you in advance.
How to keep app running alive in background in IOS 7 without affecting the battery life.
There's no reason for the app to be killed if it has background location tracking functionality in the Info.plist file and doesn't try to abuse the benefits of that permission.
I'm not sure what's your use case for the tracking functionality, but -- together with an assumption that if there's no record from some period, the tracked device didn't change the location -- setting a distance filter would allow to track the location all the time.
That also allows to put a smaller burden on device's battery, because in certain activity types handled by CLLocationManager, the device may put the location service in idle state if it doesn't detect any significant movement.
if you want to keep app active in background and don't want to go to appstore for some reason (for example you are developing something for your company with using enterprise developer program), you should check deferredLocationUpdates(even on devices which doesn't support them, you just get error in your delegate but app will work) and don't call stopLocationUpdates while in background.(if you use this on app for appstore you have to explain why you needed this to apple of course).
My app uses iCloud (key-value store) to sync an unique id between multiple devices. This works accept at the point were it really has to work, at the first launch of the app. It looks like the device isn't yet familiar with the values from iCloud at first launch, only after the app is installed and has been running for a while.
I check for the iCloud value in the viewDidLoad function on main view of the app.
So, my questions:
Is this the expected behavior?
If yes, is there another solution?
Could it be the case this is only a problem when running from Xcode, not the shipping version? If so, how to test?
Thanks!
Jasper
I had a similar issue where the NSUbiquitousKeyValueStoreDidChangeExternallyNotification wasn't triggering on the first launch after install, no matter how long I waited. Setting an initial key in the NSUBiquitousKeyValueStore seemed to solve this.
Immediately after adding the observer to the default store, I call:
[[NSUbiquitousKeyValueStore defaultStore] setString:#"testValue" forKey:#"testKey"];
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
I use different keys (i.e. not testKey) for the actual data I want to sync.
When you first run an iCloud enabled App it has to pull all the data from Apple servers. The time it takes to do so depends on many things like what kind of network you're currently on (Edge, 3G, GPRS, WLAN). It also depends on how much traffic the iCloud server currently has to handle so the request to the iCloud server may take a few more seconds, no matter what type of network connectivity you have.
To sum it up: Yes, it sounds absolutely normal.
If running your App depends on those settings consider implementing a "Wait" or "Loading" view that stays on the screen as long as it takes for the App to perform a initial synch and load all needed data from the cloud. To not block the UI forever also implement a timeout for this view (if iCloud data not loaded within X seconds, dismiss the view and notify user).
You have no guarantee NSUbiquitousKeyValueStore would have finished its first synchronization as your app is launched for the first time. (In fact, on iOS 5, it's often starting to sync as you launch your app for the first time).
There is no way to know if the first initial sync has already happened, is ongoing or has finished. You can (in fact should) subscribe to NSUbiquitousKeyValueStoreDidChangeExternallyNotification. The trick is that if your store is empty on the iCloud server, you won't get any notification after the initial sync (since your local store is empty and the cloud store is empty as well, nothing really changed "externally" after the initial sync…)
Normally, you should not rely on the initial sync being done.
Be optimist at launch, even if your store is empty, push your values (e.g. your unique id) right away. If the initial sync happens concurrently or after and there is already some value on the server, your local values will be reset to the server values and you will get the NSUbiquitousKeyValueStoreDidChangeExternallyNotification notification with the NSUbiquitousKeyValueStoreInitialSyncChange reason.
Finally, if you really think knowing about the initial sync being completed or not, please file a bug to bugreport.apple.com and explain why you really need that.
I have created a web-service app and i want to populate my view controllers according to the response i fetch(via GET) in main thread. But i want to create a scheduled timer which will go and control my server, if there becomes any difference(let's say if the count of an array has changed) i will create a local notification. As far as i read from here and some google results, i cant run my app in background more then ten minutes expect from some special situations(Audio, Vo-IP, GPS).. But i need to control the server at least one per minute.. Can anyone offer some idea-or link please?
EDIT
I will not sell the app in store, just for a local area network. Let's say, from the server i will send some text messages to the users and if a new message comes, the count of messages array will increment, in this situation i will create a notification. I need to keep this 'controlling' routing alive forever, whether in foreground or background. Does GCD give such a solution do anyone have any idea?
Just simply play a mute audio file in loop in the background, OR, ping the user's location in the background. Yes, that will drain the battery a bit, but it's a simple hack for in-home applications. Just remember to enable the background types in your Info.plist!
Note: "[...] I fetch (via GET) in main thread." This is not a good approach. You should never fetch any network resources on the main thread. Why? Because your GUI, which is maintained by the main thread, will become unresponsive whenever a fetch isn't instantaneous. Any lag spike on the network results in a less than desirable user experience.
Answer: Aside from the listed special situations, you can't run background apps. The way I see it:
Don't put the app in the background. (crappy solution)
Try putting another "entity" between the app and the "server". I don't know why you "need to control the server at least one per minute" but perhaps you can delegate this "control" to another process outside the device?
.
iOS app -> some form of proxy server -> server which requires
"babysitting" every minute.