-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
140 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |