Question

What is the best way to track App usage time and time a user spends viewing a Screen (or interacting with a UIView) for use within the App itself? Google Analytics seems to do a wonderful job, but the numbers I want to use inside the App itself to unlock items and areas of the App.

Was it helpful?

Solution

You could probably roll your own solution based on Core Data, or if your data is small you could even think of using NSDefaults. Here's a good start. It involves having a base view controller which you should inherit from in each view controller you want to measure the time spent:

@interface BaseViewController : UIViewController

- (NSString *)screenKey;
+ (NSInteger)secondsInScreen:(NSString *)screenKey;

@end

The implementation simply measures the seconds between the appearance of the screen until it disappears. It's very important to notice the appDidEnterForeground and appDidEnterBackground notifications. When you send your app to the background or it comes back to the foreground, viewDidAppear and viewDidDisappear are not called.

#import "BaseViewController.h"

@implementation BaseViewController {
    NSDate *_startDate;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self startMeasuring];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [self stopMeasuring];
}

- (void)appDidEnterBackground:(NSNotification *)not {
    [self stopMeasuring];    
}

- (void)appDidEnterForeground:(NSNotification *)not {
    [self startMeasuring];
}

- (void)startMeasuring {
    _startDate = [NSDate date];
}

- (void)stopMeasuring {
    NSInteger secondsInScreen = ABS([_startDate timeIntervalSinceNow]);
    [self addSecondsToScreen:secondsInScreen];
}

- (NSString *)screenKey {
    // Subclasses must override this method
    return @"";
}

- (void)addSecondsToScreen:(NSInteger)seconds {
    NSString *key = [self screenKey];
    if (key.length > 0) {
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSNumber *s = [defaults objectForKey:key];
        NSInteger addedSeconds = s.integerValue + seconds;
        [defaults setObject:[NSNumber numberWithInteger:addedSeconds] forKey:[self screenKey]];
        [defaults synchronize];
    }
}

+ (NSInteger)secondsInScreen:(NSString *)screenKey {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSNumber *s = [defaults objectForKey:screenKey];
    return s.integerValue;
}

@end

Your subclasses must override screenKey retuning a unique identifier for each screen you want to measure. There's a static method in BaseViewController that allows you to get the sum of seconds spent in each screen.

This is a simple way of doing it. From a design point of view, it would be better to store this information in Core Data and to separate the view controller logic from the storage of that data (the static method secondsInScreen should probably be in another class). But it's a good, working start.

OTHER TIPS

I think you would like to get app usage time to enable new features in the app or give some gifts for your users right?

To reach this, don't use any SDK to track audience like Google Analytics and Flurry for example. Both are for a different purpose you want to do.

A very very simple approach is to store locally using NSUserDefaults the session time of some user, or you can store more detailed information about this using CoreData or SQLite.

The iOS provide a lot of options to you do that, for example, each time the user start the session or open some screen, you can store some NSDate or mach_abosulte_time to save the time of user started the session/screen and you can get the offset time when the app goes to background or when the user closes the screen.

And if you want to store this remotely (server), you can create a service to send this time while the app is visible.

I hope this first insight can help you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top