Remove unnecessary files

This commit is contained in:
Vishnu Mohandas 2021-05-21 18:58:26 +05:30
parent 38194af6e3
commit c3885c195a
24 changed files with 0 additions and 1869 deletions

View file

@ -28,11 +28,6 @@ android {
}
}
repositories {
maven {
url "$buildDir/repo"
}
}
}
}

View file

@ -1,45 +0,0 @@
//
// RNBackgroundFetchManager.h
// RNBackgroundFetch
//
// Created by Christopher Scott on 2016-08-02.
// Copyright © 2016 Christopher Scott. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <BackgroundTasks/BackgroundTasks.h>
@interface TSBackgroundFetch : NSObject
@property (nonatomic) BOOL stopOnTerminate;
@property (readonly) BOOL configured;
@property (readonly) BOOL active;
@property (readonly) NSString *fetchTaskId;
+ (TSBackgroundFetch *)sharedInstance;
-(void) didFinishLaunching;
-(void) registerAppRefreshTask;
-(void) registerBGProcessingTask:(NSString*)identifier;
-(void) configure:(NSTimeInterval)delay callback:(void(^)(UIBackgroundRefreshStatus status))callback;
-(NSError*) scheduleProcessingTaskWithIdentifier:(NSString*)identifier delay:(NSTimeInterval)delay periodic:(BOOL)periodic callback:(void (^)(NSString* taskId, BOOL timeout))callback;
-(NSError*) scheduleProcessingTaskWithIdentifier:(NSString*)identifier delay:(NSTimeInterval)delay periodic:(BOOL)periodic requiresExternalPower:(BOOL)requiresExternalPower requiresNetworkConnectivity:(BOOL)requiresNetworkConnectivity callback:(void (^)(NSString* taskId, BOOL timeout))callback;
-(void) addListener:(NSString*)componentName callback:(void (^)(NSString* componentName))callback;
-(void) addListener:(NSString*)componentName callback:(void (^)(NSString* componentName))callback timeout:(void (^)(NSString* componentName))timeout;
-(void) removeListener:(NSString*)componentName;
-(BOOL) hasListener:(NSString*)componentName;
-(NSError*) start:(NSString*)identifier;
-(void) stop:(NSString*)identifier;
-(void) finish:(NSString*)tag;
-(void) status:(void(^)(UIBackgroundRefreshStatus status))callback;
// @deprecated API
-(void) performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))handler applicationState:(UIApplicationState)state;
@end

View file

@ -1,6 +0,0 @@
framework module TSBackgroundFetch {
umbrella header "TSBackgroundFetch.h"
export *
module * { export * }
}

View file

@ -1,151 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Headers/TSBackgroundFetch.h</key>
<data>
6IaHDuPW1C0nWBp03yKGD5PrgTY=
</data>
<key>Info.plist</key>
<data>
/q6b6t8hcxgtnV2U/r/pxyTm1is=
</data>
<key>Modules/module.modulemap</key>
<data>
4NbofBeHHFHeUWRZ1ZcIkl3/T3w=
</data>
</dict>
<key>files2</key>
<dict>
<key>Headers/TSBackgroundFetch.h</key>
<dict>
<key>hash</key>
<data>
6IaHDuPW1C0nWBp03yKGD5PrgTY=
</data>
<key>hash2</key>
<data>
Q6MbZjcbrHTACLwceQDEESRGhY9/uOOu7bCb71fOAfk=
</data>
</dict>
<key>Modules/module.modulemap</key>
<dict>
<key>hash</key>
<data>
4NbofBeHHFHeUWRZ1ZcIkl3/T3w=
</data>
<key>hash2</key>
<data>
ZZoRDGe9SOWekYXO71UHMmkagz+I18vRneUTVMd0WnY=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^[^/]+$</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

File diff suppressed because one or more lines are too long

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:TSBackgroundFetch.xcodeproj">
</FileRef>
</Workspace>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Latest</string>
</dict>
</plist>

View file

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View file

@ -1,39 +0,0 @@
//
// TSBGAppRefreshSubscriber.h
// TSBackgroundFetch
//
// Created by Christopher Scott on 2020-02-07.
// Copyright © 2020 Christopher Scott. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <BackgroundTasks/BackgroundTasks.h>
@interface TSBGAppRefreshSubscriber : NSObject
+(void)load;
+(NSMutableDictionary *)subscribers;
+(void) add:(TSBGAppRefreshSubscriber*)tsTask;
+(void) remove:(TSBGAppRefreshSubscriber*)tsTask;
+(TSBGAppRefreshSubscriber*) get:(NSString*)identifier;
+(void) execute;
+(BOOL) onTimeout;
+(void)registerTaskScheduler API_AVAILABLE(ios(13));
+(BOOL)useTaskScheduler;
@property (nonatomic) NSString* identifier;
@property (copy) void (^callback) (NSString*);
@property (copy) void (^timeout) (NSString*);
@property (nonatomic, readonly) BOOL enabled;
@property (nonatomic, readonly) BOOL executed;
@property (nonatomic, readonly) BOOL finished;
-(instancetype) initWithIdentifier:(NSString*)identifier callback:(void (^)(NSString* taskId))callback timeout:(void (^)(NSString* taskId))timeout;
-(void) execute;
-(void) onTimeout;
-(void) finish;
-(void) destroy;
@end

View file

@ -1,188 +0,0 @@
//
// TSBGAppRefreshSubscriber.m
// TSBackgroundFetch
//
// Created by Christopher Scott on 2020-02-07.
// Copyright © 2020 Christopher Scott. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "TSBGAppRefreshSubscriber.h"
#import "TSBackgroundFetch.h"
static NSString *const TAG = @"TSBGAppRefreshSubscriber";
static NSMutableDictionary *_subscribers;
static BOOL _hasRegisteredTaskScheduler = NO;
@implementation TSBGAppRefreshSubscriber {
}
+(void)load {
[[self class] subscribers];
}
+ (NSMutableDictionary*)subscribers
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
_subscribers = [NSMutableDictionary new];
// Load the set of taskIds, eg: ["foo, "bar"]
NSArray *subscribers = [defaults objectForKey:TAG];
// Foreach taskId, load TSBGTask config from NSDefaults, eg: "TSBackgroundFetch:foo"
for (NSString *identifier in subscribers) {
TSBGAppRefreshSubscriber *subscriber = [[TSBGAppRefreshSubscriber alloc] initWithIdentifier:identifier];
[_subscribers setObject:subscriber forKey:identifier];
}
NSLog(@"[%@ load]: %@", TAG, _subscribers);
});
return _subscribers;
}
+ (TSBGAppRefreshSubscriber*) get:(NSString*)identifier {
@synchronized (_subscribers) {
return [_subscribers objectForKey:identifier];
}
}
+ (void) add:(TSBGAppRefreshSubscriber*)subscriber {
@synchronized (_subscribers) {
[_subscribers setObject:subscriber forKey:subscriber.identifier];
}
}
+ (void) remove:(TSBGAppRefreshSubscriber*)subscriber {
@synchronized (_subscribers) {
[_subscribers removeObjectForKey:subscriber.identifier];
}
}
+(void)registerTaskScheduler{
_hasRegisteredTaskScheduler = YES;
}
+(BOOL)useTaskScheduler {
return _hasRegisteredTaskScheduler;
}
+(void) execute {
NSArray *subscribers = [[self subscribers] allValues];
for (TSBGAppRefreshSubscriber *subscriber in subscribers) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[subscriber execute];
});
}
}
+(BOOL) onTimeout {
BOOL foundTimeoutHandler = NO;
NSArray *subscribers = [[self subscribers] allValues];
for (TSBGAppRefreshSubscriber *subscriber in subscribers) {
foundTimeoutHandler = YES;
if (subscriber.timeout) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[subscriber onTimeout];
});
} else {
[[TSBackgroundFetch sharedInstance] finish:subscriber.identifier];
}
}
return foundTimeoutHandler;
}
-(instancetype)init {
self = [super init];
_enabled = YES;
_finished = NO;
_executed = NO;
return self;
}
-(instancetype) initWithIdentifier:(NSString*)identifier {
self = [self init];
if (self) {
_identifier = identifier;
}
return self;
}
-(instancetype) initWithIdentifier:(NSString*)identifier callback:(void (^)(NSString* taskId))callback timeout:(void (^)(NSString* taskId))timeout {
self = [self init];
if (self) {
_identifier = identifier;
_callback = callback;
_timeout = timeout;
[self save];
@synchronized (_subscribers) {
[_subscribers setObject:self forKey:identifier];
}
}
return self;
}
-(void) execute {
if (_executed || !_callback) return;
_executed = YES;
_finished = NO;
dispatch_async(dispatch_get_main_queue(), ^(void) {
self.callback(self.identifier);
});
}
-(void) onTimeout {
if (!_timeout) {
[self finish];
return;
}
if (!_finished) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
self.timeout(self.identifier);
});
}
}
-(void) finish {
_finished = YES;
_executed = NO;
}
-(void) destroy {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *subscribers = [[defaults objectForKey:TAG] mutableCopy];
[TSBGAppRefreshSubscriber remove:self];
if (!subscribers) {
subscribers = [NSMutableArray new];
}
if ([subscribers containsObject:_identifier]) {
[subscribers removeObject:_identifier];
[defaults setObject:subscribers forKey:TAG];
}
}
-(void) save {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *subscribers = [[defaults objectForKey:TAG] mutableCopy];
if (!subscribers) {
subscribers = [NSMutableArray new];
}
if ([subscribers containsObject:_identifier]) {
return;
}
[subscribers addObject:_identifier];
[defaults setObject:subscribers forKey:TAG];
}
-(NSString*) description {
return [NSString stringWithFormat:@"<%@ identifier=%@, executed=%d, enabled=%d>", TAG, _identifier, _executed, _enabled];
}
@end

View file

@ -1,52 +0,0 @@
//
// TSBGTask.h
// TSBackgroundFetch
//
// Created by Christopher Scott on 2020-01-23.
// Copyright © 2020 Christopher Scott. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <BackgroundTasks/BackgroundTasks.h>
@interface TSBGTask : NSObject
@property (nonatomic) BGTask* task API_AVAILABLE(ios(13.0));
@property (nonatomic) NSString* identifier;
@property (copy) void (^callback)(NSString*, BOOL);
@property (nonatomic) NSTimeInterval delay;
@property (nonatomic, readonly) BOOL executed;
@property (nonatomic) BOOL periodic;
@property (nonatomic) BOOL enabled;
@property (nonatomic, readonly) BOOL finished;
@property (nonatomic) BOOL stopOnTerminate;
@property (nonatomic) BOOL requiresExternalPower;
@property (nonatomic) BOOL requiresNetworkConnectivity;
+(void)load;
+(NSMutableArray *)tasks;
+(void) add:(TSBGTask*)tsTask;
+(void) remove:(TSBGTask*)tsTask;
+(TSBGTask*) get:(NSString*)identifier;
+(void)registerForTaskWithIdentifier:(NSString*)identifier;
+(BOOL)useProcessingTaskScheduler;
-(instancetype) initWithIdentifier:(NSString*)identifier delay:(NSTimeInterval)delay periodic:(BOOL)periodic callback:(void (^)(NSString* taskId, BOOL timeout))callback;
-(instancetype) initWithIdentifier:(NSString*)identifier delay:(NSTimeInterval)delay periodic:(BOOL)periodic requiresExternalPower:(BOOL)requiresExternalPower requiresNetworkConnectivity:(BOOL)requiresNetworkConnectivity callback:(void (^)(NSString* taskId, BOOL timeout))callback;
-(instancetype) initWithDictionary:(NSDictionary*)config;
-(BOOL) execute;
-(void) finish:(BOOL)success;
-(NSError*) schedule;
-(void) stop;
-(void) setTask:(BGProcessingTask*)task API_AVAILABLE(ios(13));
-(void) destroy;
-(void) save;
@end

View file

@ -1,297 +0,0 @@
//
// TSBGTask.m
// TSBackgroundFetch
//
// Created by Christopher Scott on 2020-01-23.
// Copyright © 2020 Christopher Scott. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "TSBGTask.h"
static NSString *const TAG = @"TSBackgroundFetch";
static NSString *const TASKS_STORAGE_KEY = @"TSBackgroundFetch:tasks";
static BOOL _hasRegisteredProcessingTaskScheduler = NO;
static NSString *const ERROR_PROCESSING_TASK_NOT_REGISTERED = @"Background procssing task was not registered in AppDelegate didFinishLaunchingWithOptions. See iOS Setup Guide.";
static NSString *const ERROR_PROCESSING_TASK_NOT_AVAILABLE = @"Background procssing tasks are only available with iOS 13+";
static NSMutableArray *_tasks;
@implementation TSBGTask {
BOOL scheduled;
}
#pragma mark Class Methods
+(void)registerForTaskWithIdentifier:(NSString*)identifier API_AVAILABLE(ios(13)) {
_hasRegisteredProcessingTaskScheduler = YES;
NSLog(@"[%@ registerForTaskWithIdentifier: %@", TAG, identifier);
[[BGTaskScheduler sharedScheduler] registerForTaskWithIdentifier:identifier usingQueue:nil launchHandler:^(BGTask* task) {
TSBGTask *tsTask = [self get:task.identifier];
if (!tsTask) {
NSLog(@"[%@ registerForTaskWithIdentifier launchHandler] ERROR: Failed to find TSBGTask in Fetch event: %@", TAG, task.identifier);
[task setTaskCompletedWithSuccess:NO];
return;
}
[tsTask setTask:(BGProcessingTask*)task];
}];
}
+(BOOL)useProcessingTaskScheduler {
return _hasRegisteredProcessingTaskScheduler;
}
+(void)load {
[[self class] tasks];
}
+ (NSMutableArray*)tasks
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
_tasks = [NSMutableArray new];
// Load the set of taskIds, eg: ["foo, "bar"]
NSArray *taskIds = [defaults objectForKey:TASKS_STORAGE_KEY];
// Foreach taskId, load TSBGTask config from NSDefaults, eg: "TSBackgroundFetch:foo"
for (NSString *taskId in taskIds) {
NSString *key = [NSString stringWithFormat:@"%@:%@", TAG, taskId];
NSDictionary *config = [defaults objectForKey:key];
TSBGTask *tsTask = [[TSBGTask alloc] initWithDictionary:config];
[_tasks addObject:tsTask];
}
NSLog(@"[%@ load]: %@", TAG, _tasks);
});
@synchronized (_tasks) {
return [_tasks copy];
}
}
+ (TSBGTask*) get:(NSString*)identifier {
@synchronized (_tasks) {
for (TSBGTask *tsTask in _tasks) {
if ([tsTask.identifier isEqualToString:identifier]) {
return tsTask;
}
}
}
return nil;
}
+ (void) add:(TSBGTask*)tsTask {
@synchronized (_tasks) {
[_tasks addObject:tsTask];
}
}
+ (void) remove:(TSBGTask*)tsTask {
@synchronized (_tasks) {
[_tasks removeObject:tsTask];
}
}
# pragma mark Instance Methods
-(instancetype)init {
self = [super init];
scheduled = NO;
_enabled = NO;
_executed = NO;
_finished = NO;
_requiresNetworkConnectivity = NO;
_requiresExternalPower = NO;
return self;
}
/// @deprecated
-(instancetype) initWithIdentifier:(NSString*)identifier delay:(NSTimeInterval)delay periodic:(BOOL)periodic callback:(void (^)(NSString* taskId, BOOL timeout))callback {
return [self initWithIdentifier:identifier delay:delay periodic:periodic requiresExternalPower:NO requiresNetworkConnectivity:NO callback:callback];
}
-(instancetype) initWithIdentifier:(NSString*)identifier delay:(NSTimeInterval)delay periodic:(BOOL)periodic requiresExternalPower:(BOOL)requiresExternalPower requiresNetworkConnectivity:(BOOL)requiresNetworkConnectivity callback:(void (^)(NSString* taskId, BOOL timeout))callback {
self = [self init];
if (self) {
_identifier = identifier;
_delay = delay;
_periodic = periodic;
_requiresExternalPower = requiresExternalPower;
_requiresNetworkConnectivity = requiresNetworkConnectivity;
[TSBGTask add:self];
}
return self;
}
-(instancetype) initWithDictionary:(NSDictionary*)config {
self = [self init];
if (self) {
_identifier = [config objectForKey:@"identifier"];
_delay = [[config objectForKey:@"delay"] longValue];
_periodic = [[config objectForKey:@"periodic"] boolValue];
_enabled = [[config objectForKey:@"enabled"] boolValue];
if ([config objectForKey:@"requiresExternalPower"]) {
_requiresExternalPower = [[config objectForKey:@"requiresExternalPower"] boolValue];
}
if ([config objectForKey:@"requiresNetworkConnectivity"]) {
_requiresNetworkConnectivity = [[config objectForKey:@"requiresNetworkConnectivity"] boolValue];
}
}
return self;
}
- (NSError*) schedule {
if (@available (iOS 13.0, *)) {
if (![TSBGTask useProcessingTaskScheduler]) {
return [[NSError alloc] initWithDomain:TAG code:0 userInfo:@{NSLocalizedFailureReasonErrorKey:ERROR_PROCESSING_TASK_NOT_REGISTERED}];
}
NSLog(@"[%@ scheduleProcessingTask] %@", TAG, self);
BGTaskScheduler *scheduler = [BGTaskScheduler sharedScheduler];
if (scheduled) {
[[BGTaskScheduler sharedScheduler] cancelTaskRequestWithIdentifier:_identifier];
}
BGProcessingTaskRequest *request = [[BGProcessingTaskRequest alloc] initWithIdentifier:_identifier];
// TODO Configurable.
request.requiresExternalPower = _requiresExternalPower;
request.requiresNetworkConnectivity = _requiresNetworkConnectivity;
request.earliestBeginDate = [NSDate dateWithTimeIntervalSinceNow:_delay];
NSError *error = nil;
[scheduler submitTaskRequest:request error:&error];
if (!error) {
scheduled = YES;
if (!_enabled) {
_enabled = YES;
[self save];
}
}
return error;
} else {
return [[NSError alloc] initWithDomain:TAG code:-1 userInfo:@{NSLocalizedFailureReasonErrorKey:ERROR_PROCESSING_TASK_NOT_AVAILABLE}];
}
}
- (void) stop {
_enabled = NO;
scheduled = NO;
[self destroy];
if (@available(iOS 13.0, *)) {
[[BGTaskScheduler sharedScheduler] cancelTaskRequestWithIdentifier:_identifier];
}
}
-(void) setTask:(BGProcessingTask*)task {
scheduled = NO;
_task = task;
task.expirationHandler = ^{
NSLog(@"[%@ expirationHandler] WARNING: %@ '%@' expired before #finish was executed.", TAG, NSStringFromClass([self.task class]), self.identifier);
[self onTimeout];
// TODO Disabled with onTimeout implementation.
//[self finish:NO];
};
// If no callback registered for TSTask, the app was launched in background. The event will be handled once task is scheduled.
if (_callback) {
[self execute];
}
}
- (BOOL) execute {
if (@available(iOS 13.0, *)) {
if ([TSBGTask useProcessingTaskScheduler] && _periodic && !scheduled) {
[self schedule];
}
}
_finished = NO;
if (_callback) {
_callback(_identifier, NO);
_executed = YES;
return YES;
} else {
return NO;
}
}
- (BOOL) onTimeout {
if (_callback) {
_callback(_identifier, YES);
return YES;
} else {
return NO;
}
}
-(void) finish:(BOOL)success {
[_task setTaskCompletedWithSuccess:success];
_finished = YES;
_executed = NO;
_task = nil;
if (!_periodic) {
[self destroy];
}
}
-(void) save {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *taskIds = [[defaults objectForKey:TASKS_STORAGE_KEY] mutableCopy];
if (!taskIds) {
taskIds = [NSMutableArray new];
}
if (![taskIds containsObject:_identifier]) {
[taskIds addObject:_identifier];
[defaults setObject:taskIds forKey:TASKS_STORAGE_KEY];
}
NSString *key = [NSString stringWithFormat:@"%@:%@", TAG, _identifier];
NSLog(@"[TSBGTask save]: %@", self);
[defaults setObject:[self toDictionary] forKey:key];
}
-(void) destroy {
[TSBGTask remove:self];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *taskIds = [[defaults objectForKey:TASKS_STORAGE_KEY] mutableCopy];
if (!taskIds) {
taskIds = [NSMutableArray new];
}
if ([taskIds containsObject:_identifier]) {
[taskIds removeObject:_identifier];
[defaults setObject:taskIds forKey:TASKS_STORAGE_KEY];
}
NSString *key = [NSString stringWithFormat:@"%@:%@", TAG, _identifier];
if ([defaults objectForKey:key]) {
[defaults removeObjectForKey:key];
}
NSLog(@"[TSBGTask destroy] %@", _identifier);
}
-(NSDictionary*) toDictionary {
return @{
@"identifier": _identifier,
@"delay": @(_delay),
@"periodic": @(_periodic),
@"enabled": @(_enabled),
@"requiresExternalPower": @(_requiresExternalPower),
@"requiresNetworkConnectivity": @(_requiresNetworkConnectivity)
};
}
-(NSString*) description {
return [NSString stringWithFormat:@"<TSBGTask identifier=%@, delay=%ld, periodic=%d requiresNetworkConnectivity=%d requiresExternalPower=%d, enabled=%d>", _identifier, (long)_delay, _periodic, _requiresNetworkConnectivity, _requiresExternalPower, _enabled];
}
@end

View file

@ -1,47 +0,0 @@
//
// RNBackgroundFetchManager.h
// RNBackgroundFetch
//
// Created by Christopher Scott on 2016-08-02.
// Copyright © 2016 Christopher Scott. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <BackgroundTasks/BackgroundTasks.h>
@interface TSBackgroundFetch : NSObject
@property (nonatomic) BOOL stopOnTerminate;
@property (readonly) BOOL configured;
@property (readonly) BOOL active;
@property (readonly) NSString *fetchTaskId;
@property (copy) void (^completionHandler)(UIBackgroundFetchResult);
@property (nonatomic) UIBackgroundTaskIdentifier backgroundTask;
+ (TSBackgroundFetch *)sharedInstance;
-(void) didFinishLaunching;
-(void) registerAppRefreshTask;
-(void) registerBGProcessingTask:(NSString*)identifier;
-(void) configure:(NSTimeInterval)delay callback:(void(^)(UIBackgroundRefreshStatus status))callback;
-(NSError*) scheduleProcessingTaskWithIdentifier:(NSString*)identifier delay:(NSTimeInterval)delay periodic:(BOOL)periodic callback:(void (^)(NSString* taskId, BOOL timeout))callback;
-(NSError*) scheduleProcessingTaskWithIdentifier:(NSString*)identifier delay:(NSTimeInterval)delay periodic:(BOOL)periodic requiresExternalPower:(BOOL)requiresExternalPower requiresNetworkConnectivity:(BOOL)requiresNetworkConnectivity callback:(void (^)(NSString* taskId, BOOL timeout))callback;
-(void) addListener:(NSString*)componentName callback:(void (^)(NSString* componentName))callback;
-(void) addListener:(NSString*)componentName callback:(void (^)(NSString* componentName))callback timeout:(void (^)(NSString* componentName))timeout;
-(void) removeListener:(NSString*)componentName;
-(BOOL) hasListener:(NSString*)componentName;
-(NSError*) start:(NSString*)identifier;
-(void) stop:(NSString*)identifier;
-(void) finish:(NSString*)tag;
-(void) status:(void(^)(UIBackgroundRefreshStatus status))callback;
// @deprecated API
-(void) performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))handler applicationState:(UIApplicationState)state;
@end

View file

@ -1,365 +0,0 @@
//
// RNBackgroundFetchManager.m
// RNBackgroundFetch
//
// Created by Christopher Scott on 2016-08-02.
// Copyright © 2016 Christopher Scott. All rights reserved.
//
#import "TSBackgroundFetch.h"
#import "TSBGTask.h"
#import "TSBGAppRefreshSubscriber.h"
static NSString *const TAG = @"TSBackgroundFetch";
static NSString *const BACKGROUND_REFRESH_TASK_ID = @"com.transistorsoft.fetch";
static NSString *const PERMITTED_IDENTIFIERS_KEY = @"BGTaskSchedulerPermittedIdentifiers";
@implementation TSBackgroundFetch {
BOOL enabled;
NSTimeInterval minimumFetchInterval;
id bgAppRefreshTask;
BOOL fetchScheduled;
}
+ (TSBackgroundFetch *)sharedInstance
{
static TSBackgroundFetch *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[TSBGTask load];
[TSBGAppRefreshSubscriber load];
instance = [[self alloc] init];
});
return instance;
}
-(instancetype)init
{
self = [super init];
fetchScheduled = NO;
minimumFetchInterval = UIApplicationBackgroundFetchIntervalMinimum;
_fetchTaskId = BACKGROUND_REFRESH_TASK_ID;
_stopOnTerminate = YES;
_configured = NO;
_active = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppTerminate) name:UIApplicationWillTerminateNotification object:nil];
return self;
}
- (void) didFinishLaunching {
NSArray *permittedIdentifiers = [[NSBundle mainBundle] objectForInfoDictionaryKey:PERMITTED_IDENTIFIERS_KEY];
if (!permittedIdentifiers) return;
for (NSString *identifier in permittedIdentifiers) {
if ([identifier isEqualToString:BACKGROUND_REFRESH_TASK_ID]) {
[self registerAppRefreshTask];
} else {
[self registerBGProcessingTask:identifier];
}
}
}
- (void) registerAppRefreshTask {
if (@available(iOS 13.0, *)) {
[TSBGAppRefreshSubscriber registerTaskScheduler];
[[BGTaskScheduler sharedScheduler] registerForTaskWithIdentifier:BACKGROUND_REFRESH_TASK_ID usingQueue:nil launchHandler:^(BGTask* task) {
[self handleBGAppRefreshTask:(BGAppRefreshTask*)task];
}];
}
}
- (void) registerBGProcessingTask:(NSString *)identifier {
if (@available(iOS 13.0, *)) {
[TSBGTask registerForTaskWithIdentifier:identifier];
}
}
- (NSError*) scheduleBGAppRefresh {
if (fetchScheduled) return nil;
NSLog(@"[%@ scheduleBGAppRefresh] %@", TAG, BACKGROUND_REFRESH_TASK_ID);
NSError *error = nil;
if (@available (iOS 13.0, *)) {
if ([TSBGAppRefreshSubscriber useTaskScheduler]) {
BGTaskScheduler *scheduler = [BGTaskScheduler sharedScheduler];
BGAppRefreshTaskRequest *request = [[BGAppRefreshTaskRequest alloc] initWithIdentifier:BACKGROUND_REFRESH_TASK_ID];
request.earliestBeginDate = [NSDate dateWithTimeIntervalSinceNow:minimumFetchInterval];
[scheduler submitTaskRequest:request error:&error];
// Handle case for Simulator where BGTaskScheduler doesn't work.
if ((error != nil) && (error.code == BGTaskSchedulerErrorCodeUnavailable)) {
NSLog(@"[%@] BGTaskScheduler failed to register fetch-task and will fall-back to old API. This is likely due to running in the iOS Simulator (%@)", TAG, error);
[self setMinimumFetchInterval];
error = nil;
}
} else {
[self setMinimumFetchInterval];
}
} else {
[self setMinimumFetchInterval];
}
if (!error) {
fetchScheduled = YES;
}
return error;
}
-(void) cancelBGAppRefresh {
if (@available (iOS 13.0, *)) {
BGTaskScheduler *scheduler = [BGTaskScheduler sharedScheduler];
[scheduler cancelTaskRequestWithIdentifier:BACKGROUND_REFRESH_TASK_ID];
fetchScheduled = NO;
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalNever];
});
}
}
-(void) setMinimumFetchInterval {
__block NSTimeInterval interval = minimumFetchInterval;
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:interval];
});
}
/// Callback from BGTaskScheduler
-(void) handleBGAppRefreshTask:(BGAppRefreshTask*)task API_AVAILABLE(ios(13.0)) {
NSLog(@"[%@ handleBGAppRefreshTask]", TAG);
__block BGAppRefreshTask *weakTask = task;
task.expirationHandler = ^{
NSLog(@"[%@ handleBGAppRefreshTask] WARNING: expired before #finish was executed.", TAG);
// If any registered listeners has registered an onTimeout callback, let them run and execute #finish as desired. Otherwise, automatically setTaskCompleted immediately.
if (![TSBGAppRefreshSubscriber onTimeout] && weakTask) [weakTask setTaskCompletedWithSuccess:NO];
};
fetchScheduled = NO;
[self scheduleBGAppRefresh];
bgAppRefreshTask = task;
[TSBGAppRefreshSubscriber execute];
}
/// @deprecated Old-syle fetch callback.
- (void) performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))handler applicationState:(UIApplicationState)state {
NSLog(@"[%@ performFetchWithCompletionHandler]", TAG);
fetchScheduled = NO;
[self scheduleBGAppRefresh];
_completionHandler = handler;
if (_backgroundTask != UIBackgroundTaskInvalid) [[UIApplication sharedApplication] endBackgroundTask:_backgroundTask];
// Create a UIBackgroundTask for detecting task-expiration with old API.
_backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
if (self.completionHandler) {
[TSBGAppRefreshSubscriber onTimeout];
}
@synchronized (self) {
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}
}];
[TSBGAppRefreshSubscriber execute];
}
-(void) status:(void(^)(UIBackgroundRefreshStatus status))callback
{
dispatch_async(dispatch_get_main_queue(), ^{
callback([[UIApplication sharedApplication] backgroundRefreshStatus]);
});
}
-(void) configure:(NSTimeInterval)delay callback:(void(^)(UIBackgroundRefreshStatus status))callback {
_configured = YES;
minimumFetchInterval = delay;
[self status:^(UIBackgroundRefreshStatus status) {
if (status == UIBackgroundRefreshStatusAvailable) {
[self scheduleBGAppRefresh];
}
callback(status);
}];
}
-(NSError*) scheduleProcessingTaskWithIdentifier:(NSString*)identifier delay:(NSTimeInterval)delay periodic:(BOOL)periodic callback:(void (^)(NSString* taskId, BOOL timeout))callback {
return [self scheduleProcessingTaskWithIdentifier:identifier delay:delay periodic:periodic requiresExternalPower:NO requiresNetworkConnectivity:NO callback:callback];
}
-(NSError*) scheduleProcessingTaskWithIdentifier:(NSString*)identifier delay:(NSTimeInterval)delay periodic:(BOOL)periodic requiresExternalPower:(BOOL)requiresExternalPower requiresNetworkConnectivity:(BOOL)requiresNetworkConnectivity callback:(void (^)(NSString* taskId, BOOL timeout))callback {
TSBGTask *tsTask = [TSBGTask get:identifier];
if (tsTask) {
tsTask.delay = delay;
tsTask.periodic = periodic;
tsTask.callback = callback;
tsTask.requiresNetworkConnectivity = requiresNetworkConnectivity;
tsTask.requiresExternalPower = requiresExternalPower;
if (@available(iOS 13.0, *)) {
if (tsTask.task && !tsTask.executed) {
[tsTask execute];
return nil;
} else {
return [tsTask schedule];
}
}
} else {
tsTask = [[TSBGTask alloc] initWithIdentifier:identifier
delay:delay
periodic:periodic
requiresExternalPower:requiresExternalPower
requiresNetworkConnectivity:requiresNetworkConnectivity
callback:callback];
tsTask.callback = callback;
}
NSError *error = [tsTask schedule];
if (error) {
NSLog(@"[%@ scheduleTask] ERROR: Failed to submit task request: %@", TAG, error);
}
return error;
}
/// @deprecated.
-(void) addListener:(NSString*)componentName callback:(void (^)(NSString* componentName))callback {
[self addListener:componentName callback:callback timeout:nil];
}
-(void) addListener:(NSString*)componentName callback:(void (^)(NSString* componentName))callback timeout:(void (^)(NSString* componentName))timeout {
TSBGAppRefreshSubscriber *subscriber = [TSBGAppRefreshSubscriber get:componentName];
if (subscriber) {
subscriber.callback = callback;
subscriber.timeout = timeout;
} else {
subscriber = [[TSBGAppRefreshSubscriber alloc] initWithIdentifier:componentName callback:callback timeout:timeout];
}
if (bgAppRefreshTask || _completionHandler) {
[subscriber execute];
}
}
-(BOOL) hasListener:(NSString*)identifier {
return ([TSBGAppRefreshSubscriber get:identifier] != nil);
}
-(void) removeListener:(NSString*)identifier {
TSBGAppRefreshSubscriber *subscriber = [TSBGAppRefreshSubscriber get:identifier];
if (!subscriber) {
NSLog(@"[%@ removeListener] WARNING: Failed to find listener for identifier: %@", TAG, identifier);
return;
}
[subscriber destroy];
if ([[TSBGAppRefreshSubscriber subscribers] count] < 1) {
[self cancelBGAppRefresh];
}
}
- (NSError*) start:(NSString*)identifier {
NSLog(@"[%@ start] %@", TAG, identifier);
if (!identifier) {
return [self scheduleBGAppRefresh];
} else {
TSBGTask *tsTask = [TSBGTask get:identifier];
if (!tsTask) {
NSString *msg = [NSString stringWithFormat:@"Could not find TSBGTask %@", identifier];
NSLog(@"[%@ start] ERROR: %@", TAG, msg);
NSError *error = [[NSError alloc] initWithDomain:TAG code:-2 userInfo:@{NSLocalizedFailureReasonErrorKey:msg}];
return error;
}
tsTask.enabled = YES;
[tsTask save];
return [tsTask schedule];
}
}
- (void) stop:(NSString*)identifier {
NSLog(@"[%@ stop] %@", TAG, identifier);
if (!identifier) {
NSArray *tsTasks = [TSBGTask tasks];
for (TSBGTask *tsTask in tsTasks) {
[tsTask stop];
}
} else {
TSBGTask *tsTask = [TSBGTask get:identifier];
[tsTask stop];
}
}
- (void) finish:(NSString*)taskId {
if (!taskId) { taskId = BACKGROUND_REFRESH_TASK_ID; }
TSBGTask *tsTask = [TSBGTask get:taskId];
// Is it a scheduled-task?
if (tsTask) {
if (@available(iOS 13.0, *)) {
[tsTask finish:YES];
}
// We're done.
return;
}
// Nope, it's a background-fetch event. We have to do subscriber-counting: when all subscribers have signalled #finish, we're done.
if (!bgAppRefreshTask && !_completionHandler) {
NSLog(@"[%@ finish] %@ Called without a task to finish. Ignoring.", TAG, taskId);
return;
}
TSBGAppRefreshSubscriber *subscriber = [TSBGAppRefreshSubscriber get:taskId];
if (subscriber) {
[subscriber finish];
NSArray *subscribers = [[TSBGAppRefreshSubscriber subscribers] allValues];
long total = [subscribers count];
long count = 0;
for (TSBGAppRefreshSubscriber *subscriber in subscribers) {
if (subscriber.finished) count++;
}
NSLog(@"[%@ finish] %@ (%ld of %ld)", TAG, subscriber.identifier, count, total);
if (total != count) return;
// If we arrive here without jumping out of foreach above, all subscribers are finished.
if (bgAppRefreshTask) {
// If we arrive here, all Fetch tasks must be finished.
if (@available(iOS 13.0, *)) {
[(BGAppRefreshTask*) bgAppRefreshTask setTaskCompletedWithSuccess:YES];
}
bgAppRefreshTask = nil;
} else if (_completionHandler) {
_completionHandler(UIBackgroundFetchResultNewData);
_completionHandler = nil;
@synchronized (self) {
if (_backgroundTask != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask:_backgroundTask];
_backgroundTask = UIBackgroundTaskInvalid;
}
}
}
} else {
NSLog(@"[%@ finish] Failed to find Fetch subscriber %@", TAG, taskId);
}
}
- (void) onAppTerminate {
NSLog(@"[%@ onAppTerminate]", TAG);
if (_stopOnTerminate) {
//[self stop];
}
}
- (void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end

View file

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View file

@ -1,39 +0,0 @@
//
// TSBackgroundFetchTests.m
// TSBackgroundFetchTests
//
// Created by Christopher Scott on 2016-08-03.
// Copyright © 2016 Christopher Scott. All rights reserved.
//
#import <XCTest/XCTest.h>
@interface TSBackgroundFetchTests : XCTestCase
@end
@implementation TSBackgroundFetchTests
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testExample {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
}];
}
@end