mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Improve background task logic.
This commit is contained in:
parent
f9ce34f553
commit
c3b6de4f83
|
@ -10,6 +10,17 @@ typedef NS_ENUM(NSUInteger, BackgroundTaskState) {
|
||||||
|
|
||||||
typedef void (^BackgroundTaskCompletionBlock)(BackgroundTaskState backgroundTaskState);
|
typedef void (^BackgroundTaskCompletionBlock)(BackgroundTaskState backgroundTaskState);
|
||||||
|
|
||||||
|
// This class makes it easier and safer to use background tasks.
|
||||||
|
//
|
||||||
|
// * Uses RAII (Resource Acquisition Is Initialization) pattern.
|
||||||
|
// * Ensures completion block is called exactly once and on main thread,
|
||||||
|
// to facilitate handling "background task timed out" case, for example.
|
||||||
|
// * Ensures we properly handle the "background task could not be created"
|
||||||
|
// case.
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
//
|
||||||
|
// * Use factory method to start a background task.
|
||||||
@interface OWSBackgroundTask : NSObject
|
@interface OWSBackgroundTask : NSObject
|
||||||
|
|
||||||
- (instancetype)init NS_UNAVAILABLE;
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#import "OWSBackgroundTask.h"
|
#import "OWSBackgroundTask.h"
|
||||||
#import "AppContext.h"
|
#import "AppContext.h"
|
||||||
|
#import "Threading.h"
|
||||||
|
|
||||||
@interface OWSBackgroundTask ()
|
@interface OWSBackgroundTask ()
|
||||||
|
|
||||||
|
@ -12,6 +13,7 @@
|
||||||
// This property should only be accessed while synchronized on this instance.
|
// This property should only be accessed while synchronized on this instance.
|
||||||
@property (nonatomic) UIBackgroundTaskIdentifier backgroundTaskId;
|
@property (nonatomic) UIBackgroundTaskIdentifier backgroundTaskId;
|
||||||
|
|
||||||
|
// This property should only be accessed while synchronized on this instance.
|
||||||
@property (nonatomic, nullable) BackgroundTaskCompletionBlock completionBlock;
|
@property (nonatomic, nullable) BackgroundTaskCompletionBlock completionBlock;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -74,12 +76,14 @@
|
||||||
|
|
||||||
- (void)startBackgroundTask
|
- (void)startBackgroundTask
|
||||||
{
|
{
|
||||||
__weak typeof(self) weakSelf = self;
|
|
||||||
// beginBackgroundTaskWithExpirationHandler must be called on the main thread.
|
// beginBackgroundTaskWithExpirationHandler must be called on the main thread.
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
DispatchMainThreadSafe(^{
|
||||||
|
__weak typeof(self) weakSelf = self;
|
||||||
self.backgroundTaskId = [CurrentAppContext() beginBackgroundTaskWithExpirationHandler:^{
|
self.backgroundTaskId = [CurrentAppContext() beginBackgroundTaskWithExpirationHandler:^{
|
||||||
OWSAssert([NSThread isMainThread]);
|
// Note the usage of OWSCAssert() to avoid capturing a reference to self.
|
||||||
__strong typeof(self) strongSelf = weakSelf;
|
OWSCAssert([NSThread isMainThread]);
|
||||||
|
|
||||||
|
OWSBackgroundTask *strongSelf = weakSelf;
|
||||||
if (!strongSelf) {
|
if (!strongSelf) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +92,7 @@
|
||||||
if (strongSelf.backgroundTaskId == UIBackgroundTaskInvalid) {
|
if (strongSelf.backgroundTaskId == UIBackgroundTaskInvalid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DDLogInfo(@"%@ %@ background task expired", strongSelf.logTag, strongSelf.label);
|
DDLogInfo(@"%@ %@ background task expired.", strongSelf.logTag, strongSelf.label);
|
||||||
strongSelf.backgroundTaskId = UIBackgroundTaskInvalid;
|
strongSelf.backgroundTaskId = UIBackgroundTaskInvalid;
|
||||||
|
|
||||||
if (strongSelf.completionBlock) {
|
if (strongSelf.completionBlock) {
|
||||||
|
@ -100,6 +104,11 @@
|
||||||
|
|
||||||
// If a background task could not be begun, call the completion block.
|
// If a background task could not be begun, call the completion block.
|
||||||
if (self.backgroundTaskId == UIBackgroundTaskInvalid) {
|
if (self.backgroundTaskId == UIBackgroundTaskInvalid) {
|
||||||
|
|
||||||
|
DDLogInfo(@"%@ %@ background task could not be started.", self.logTag, self.label);
|
||||||
|
|
||||||
|
// Make a local copy of completionBlock to ensure that it is called
|
||||||
|
// exactly once.
|
||||||
BackgroundTaskCompletionBlock _Nullable completionBlock;
|
BackgroundTaskCompletionBlock _Nullable completionBlock;
|
||||||
@synchronized(self)
|
@synchronized(self)
|
||||||
{
|
{
|
||||||
|
@ -107,7 +116,7 @@
|
||||||
self.completionBlock = nil;
|
self.completionBlock = nil;
|
||||||
}
|
}
|
||||||
if (completionBlock) {
|
if (completionBlock) {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
DispatchMainThreadSafe(^{
|
||||||
completionBlock(BackgroundTaskState_CouldNotStart);
|
completionBlock(BackgroundTaskState_CouldNotStart);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -119,22 +128,24 @@
|
||||||
{
|
{
|
||||||
// Make a local copy of this state, since this method is called by `dealloc`.
|
// Make a local copy of this state, since this method is called by `dealloc`.
|
||||||
UIBackgroundTaskIdentifier backgroundTaskId;
|
UIBackgroundTaskIdentifier backgroundTaskId;
|
||||||
|
BackgroundTaskCompletionBlock _Nullable completionBlock;
|
||||||
NSString *logTag = self.logTag;
|
NSString *logTag = self.logTag;
|
||||||
NSString *label = self.label;
|
NSString *label = self.label;
|
||||||
BackgroundTaskCompletionBlock _Nullable completionBlock = self.completionBlock;
|
|
||||||
|
|
||||||
@synchronized(self)
|
@synchronized(self)
|
||||||
{
|
{
|
||||||
backgroundTaskId = self.backgroundTaskId;
|
backgroundTaskId = self.backgroundTaskId;
|
||||||
|
completionBlock = self.completionBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backgroundTaskId == UIBackgroundTaskInvalid) {
|
if (backgroundTaskId == UIBackgroundTaskInvalid) {
|
||||||
|
OWSAssert(!completionBlock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// endBackgroundTask must be called on the main thread.
|
// endBackgroundTask must be called on the main thread.
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
DispatchMainThreadSafe(^{
|
||||||
DDLogInfo(@"%@ %@ background task completed", logTag, label);
|
DDLogVerbose(@"%@ %@ background task completed.", logTag, label);
|
||||||
[CurrentAppContext() endBackgroundTask:backgroundTaskId];
|
[CurrentAppContext() endBackgroundTask:backgroundTaskId];
|
||||||
|
|
||||||
if (completionBlock) {
|
if (completionBlock) {
|
||||||
|
|
Loading…
Reference in a new issue