Skip to content

Commit

Permalink
Added MYBackgroundMonitor
Browse files Browse the repository at this point in the history
  • Loading branch information
snej committed Sep 29, 2015
1 parent a887a82 commit 2252793
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 0 deletions.
43 changes: 43 additions & 0 deletions MYBackgroundMonitor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// MYBackgroundMonitor.h
// MYUtilities
//
// Created by Jens Alfke on 9/24/15.
// Copyright © 2015 Jens Alfke. All rights reserved.
//

#import <Foundation/Foundation.h>


/** Monitors when a UIKit app enters/leaves the background, and allows the client to start a
"background task" to request more time to finish an activity. */
@interface MYBackgroundMonitor : NSObject

- (instancetype) init;

/** Explicitly stops the monitor. (So does deallocing it.) */
- (void) stop;

/** Starts a background task. Should be called from the onAppBackgrounding block.
Only one background task can be active at a time. */
- (BOOL) beginBackgroundTaskNamed: (NSString*)name;

/** Tells the OS that the current background task is done. */
- (void) endBackgroundTask;

/** YES if there is currently a background task. */
@property (readonly) BOOL hasBackgroundTask;

/** This block will be called when the app goes into the background.
The app will soon stop being scheduled for CPU time unless the block starts a background task
by calling -beginBackgroundTaskNamed:. */
@property (strong) void (^onAppBackgrounding)();

/** Called when the app returns to the foreground. */
@property (strong) void (^onAppForegrounding)();

/** Called if the OS loses its patience before -endBackgroundTask is called.
The task is implicitly ended, and the app will soon stop being scheduled for CPU time. */
@property (strong) void (^onBackgroundTaskExpired)();

@end
97 changes: 97 additions & 0 deletions MYBackgroundMonitor.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//
// MYBackgroundMonitor.m
// MYUtilities
//
// Created by Jens Alfke on 9/24/15.
// Copyright © 2015 Jens Alfke. All rights reserved.
//

#import "MYBackgroundMonitor.h"
#import <UIKit/UIKit.h>
#import <dispatch/dispatch.h>


@implementation MYBackgroundMonitor
{
NSString* _name;
UIBackgroundTaskIdentifier _bgTask;
}


@synthesize onAppBackgrounding=_onAppBackgrounding, onAppForegrounding=_onAppForegrounding;
@synthesize onBackgroundTaskExpired=_onBackgroundTaskExpired;


- (instancetype) init {
self = [super init];
if (self) {
_bgTask = UIBackgroundTaskInvalid;
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(appBackgrounding:)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(appForegrounding:)
name: UIApplicationWillEnterForegroundNotification
object: nil];
}
return self;
}


- (void) endBackgroundTask {
@synchronized(self) {
if (_bgTask != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask: _bgTask];
_bgTask = UIBackgroundTaskInvalid;
}
}
}


- (void) stop {
[self endBackgroundTask];
[[NSNotificationCenter defaultCenter] removeObserver: self];
}


- (void) dealloc {
[self stop];
}


- (BOOL) beginBackgroundTaskNamed: (NSString*)name {
@synchronized(self) {
Assert(_bgTask == UIBackgroundTaskInvalid);
_bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName: name
expirationHandler: ^{
// Process ran out of background time before endBackgroundTask was called:
[self endBackgroundTask];
if (_onBackgroundTaskExpired)
_onBackgroundTaskExpired();
}];
return (_bgTask != UIBackgroundTaskInvalid);
}
}


- (BOOL) hasBackgroundTask {
@synchronized(self) {
return _bgTask != UIBackgroundTaskInvalid;
}
}


- (void) appBackgrounding: (NSNotification*)n {
if (_onAppBackgrounding)
_onAppBackgrounding();
}


- (void) appForegrounding: (NSNotification*)n {
if (_onAppForegrounding)
_onAppForegrounding();
}


@end

0 comments on commit 2252793

Please sign in to comment.