Track time spent in application - ios

What should I use to track how long is user using my application on iOS devices?
I think I can do it like this:
Log time on App startup (application:didFinishLaunchingWithOptions:)
Log time on App ending (applicationWillTerminate:)
List item
Send report (pairs of start/exit time) to server and count time spent in app
Do you have any better ideas?
Important is to be network and resources effective
(not to send big amount of data or consume iOS resources on complex computing operations.)

Notice that applicationWillTerminate: is not necessarily called when the home button is pressed (this changed from iOS 3.X to iOS 4.0).
Take a look at applicationDidEnterBackground: and applicationWillEnterForeground:
More here.

I believe that calculating the time on the device itself would be best, considering you want this to be network and resource effective. The calculation of endTime - starTime will be very very fast (depending on your time implementation), and then you would only need to send one piece of data (the time it took) over a network instead of two (the start and end times).
Hope this helps!
N.S.

Seems like a reasonable way to do it. It's efficient enough, and depending on how you see the data, it shouldn't be more than a kilobyte or two, if that. Be wary of privacy issues though—users are really against being logged.

Your method is sound, it will have next to no overhead and get the job done nicely.

Log time on App startup (didFinishLaunchingWithOptions)
send report often with interval of 5min.
send report in applicationWillEnterbackground.(pause timer(invalidate) if u used background thread for it).because if the user enter in other app then they can close ur app by just using home button and with minus button in app manager.so u have to send report here also
resume timer with previous time in applicationWillEnterForeground.
Log time on App ending (applicationWillTerminate)
Send report (pairs of start/exit time) to server and count time spent in app

Related

iOS how to detect user has changed system time, and if not compare device time with server time

The requirement is that have to detect if the system time of iPhone is changed by user manually. For that I have used
NSNotificationCenter.defaultCenter().addObserver(self, selector: "timeChangedNotification:", name: NSSystemClockDidChangeNotification, object: nil)
and
func timeChangedNotification(notification:NSNotification){
println("Device time has been changed...")
}
But not getting the results.
Also if this time is not changed means it is automatic time provided by network then have to compare with server time.How can this be done? Please give help for the same.
As per its documentation, NSSystemClockDidChangeNotification is:
Posted whenever the system clock is changed. This can be initiated by a call to settimeofday() or the user changing values in the Date and Time Preference panel.
So unless you were expecting the user to change the date or time while your app is running, you're obviously not going to hear anything. Notifications are triggered by events.
iOS doesn't provide you with a way to ask on whose authority the system believes the time and date is the current value — whether it's carrier network time, time server time, user-supplied time or something else. There's no single server time and no way to ask for it. What you want to do cannot be done.
This code worked for me in Swift 3
NotificationCenter.default.addObserver(self, selector: #selector(ClassName.timeChangedNotification), name: NSNotification.Name.NSSystemClockDidChange, object: nil)
}
// Method get called user changed the system time manually.
func timeChangedNotification(notification:NSNotification){
print("Device time has been changed...")
}
I've tried 3 options to do this for an enterprise app that I did that requires the time to always be in sync across users. Since we have no control over the users' setting of the device time, I was also face with your predicament:
Option 1 - Using GPS time: I tried getting the GPS timestamp and comparing it with the local device time. It worked in some countries but did not work in others. Other countries return the device time for some reason.
Option 2 - Using a background process to estimate the approximate time. What you do is to get the timestamp, whenever your app goes to the background. Run a timer that fires every 5 minutes (+/- depending on your tolerance). Then calculate the estimated time by adding the 5min ticks that went by to the stored timestamp when your app becomes active. However, this approach can only detect if the time was changed while your app is already running. And not if the time was changed before your app even started.
Option 3 - Using a time-check at the backend. And this is what I ended up doing. I have a small php backend program that returns the UTC time. So every time my app is executed or returns to the foreground, my app will quickly check the time against my time-server. To handle offline cases, I store the last timestamp before the system goes to the background so you can at least check if the date/time was back-dated. Then check again with the time-server when the system goes online.
So far it's the third option that worked for me. But I guess combining 2 and 3 would even make the system more pull-proof.
It's been a while but it might be useful for anyone who will find this question in future like I did today.
You also could use NTP protocol to know real epoch time at the moment when your app enters background / foreground or in didFinishLaunching. This requires the app to be online, though. But it could help in most cases.
There are at least two open-source libraries for iOS and for Android that can help: TrueTime and Kronos.

how to handle a long wait time for data, when ios 8+ app has been backgrounded by user

I've spent a lot of time looking at the options but am still not 100% clear, so wanted to reach out for some guidance.
Scenario is this:
User submits an HTTPS request to our backend server for some data via an iOS app
Depending on the data, the first (only) request can take a REALLY long time. like, say, 10+ minutes (shocking i know)
When that payload finally does become available and is returned via the HTTPS request, we then want to use it to update the UI in background.
The assumption here is that the user has moved on to another app whilst waiting for the data to arrive (and lets also assume they haven't killed the app).
Is it possible to handle this via iOS 8+ API's without the app being force/killed by Apple when in the background ?
Could we use background task for example?
var backgroundTask: UIBackgroundTaskIdentifier
xxx.beginBackgroundTaskWithName...
etc
Before testing some code blocks we just wanted to see if someone has (a) already done this and/or (b) whether we're heading in the right direction
Thanks for your help.
You should re-think on your web service which may take almost 10 min to process. If you are not able to optimize server task processing time then below one of the idea may be help you.
You can divided your one request into multiple request to reduce processing time and get response in faster way.
Your server should sent notification to app when its done with its task. So app will came to know task is done.
I am not sure why you try to update UI when apps in background mode , you may try to update UI when users come to foreground mode from background mode.
Please check this link which show as example of long running task. Where its use a blank audio play to keep alive app background task.
You can used "Background fetch" functionality.
For learning purpose you can refer this link

Xcode - Run code each day on 00:00

I need a piece of code for Xcode (obj-c) that runs every day at 00:00.
The reason for this is because my server updates data each new day and I would like my app to synchronize with the update.
I was thinking about doing a timer that runs every minute and checks the time (from internet, not the phones time), but it seems like there could be an more efficient way.
Help or pointers really appreciated!
Thanks
Use the calendar app on your mac. Set up a recurring event every day at 0:00. At the point where you pick the type of alert, you can select an option to open a file (as opposed to a pop-up, etc.). Pick your app as the file to be opened.
When the app becomes active, register a local notification (UILocalNotification) to trigger at midnight.
Then, you can perform the updates at the app delegate's -application:didReceiveLocalNotification:
You can then cancel the notification when the application goes to background by calling the UIApplication's method -cancelLocalNotification:
I don't think it's even required to use notification here. Notification is usually on best effort basis and doesn't guarantee the delivery. This can be done in few simple steps.
Save the lastUpdated time in your iOS app. Probably in NSUserDefaults or if you're using local database you can store it there as well.
Everytime user launches the application check how much time has elapsed since last update.
If it's more than 24 hours then make an API call to your server and check if there's any new updates available (which you can determine probably from server timestamp). Get the latest data (possibly only the delta difference in stead of everything).
Update the lastUpdated time in your iOS app.

Can a background app (with a location UIBackgroundMode) use a timer to poll a server every few hours?

I have a background app with a UIBackgroundMode of location.
I would like my app to additionally contact a server every few or several hours to see if there is some new data for it (because using apple notification push would notify the user and that is not desirable).
Polling is something I would never use on any other OS, but with iOS they don't leave you much choice if there is certain functionality you would like to try to achieve.
If the polling interval is quite lengthy such as a few or several hours between polls, and the polling activity itself only lasts several seconds then the usual knee-jerk reaction about it draining battery life is greatly diminished.
Would a repeating NSTimer fire when an app is in background mode? If not is there another type of timer or mechanism available?
If it's just to check for new content, and not really time sensitive, you COULD use the significantChanges background location method...but if the user stayed fairly immobile it'd rarely/never fire. I would probably also add the update check in applicationWillEnterForeground to be more sure
No, that's not allowed. You should have a look at Push Notifications and find a server side solution.

Choosing when to send data with Flurry on iPad

I would like to add Flurry to an iPad app that is meant to stay running in the foreground for several weeks.
Flurry apparently only uploads information to its servers on events such as app start, app close, app pause, but I don't expect my app to enter those states very often. I need app feedback sooner.
Is it possible to force Flurry to send data on a timer, say every hour or two?
I found a way that seems to work. To test, I created an NSTimer that calls [FlurryAPI startSession:#"yourKeyHere"] every five minutes, then let my program run without stopping or pausing it in any way, and the event data is appearing on the Flurry server.
The comments above that method in the .h file do say "start session, attempt to send saved sessions to server", so in a sense it's documented, but it feels like a hack to have to call something called startSession more than once per application run. This is partly why I'm switching to MixPanel, which has a documented upload interval feature.

Resources