- Fix
This commit is contained in:
1 parent
b0bcfad332
commit
de4cd554f0
104 files changed
+2211
-1744
No files matched your search
+10
-7
@@ -11,10 +11,11 @@
|
||||
#import "BFCancellationToken.h"
|
||||
#import "BFCancellationTokenRegistration.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface BFCancellationToken ()
|
||||
|
||||
@property (nonatomic, assign, getter=isCancellationRequested) BOOL cancellationRequested;
|
||||
@property (nonatomic, strong) NSMutableArray *registrations;
|
||||
@property (nullable, nonatomic, strong) NSMutableArray *registrations;
|
||||
@property (nonatomic, strong) NSObject *lock;
|
||||
@property (nonatomic) BOOL disposed;
|
||||
|
||||
@@ -30,11 +31,13 @@
|
||||
|
||||
@implementation BFCancellationToken
|
||||
|
||||
@synthesize cancellationRequested = _cancellationRequested;
|
||||
|
||||
#pragma mark - Initializer
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
if (!self) return self;
|
||||
|
||||
_registrations = [NSMutableArray array];
|
||||
_lock = [NSObject new];
|
||||
@@ -124,11 +127,9 @@
|
||||
if (self.disposed) {
|
||||
return;
|
||||
}
|
||||
[self.registrations makeObjectsPerformSelector:@selector(dispose)];
|
||||
self.registrations = nil;
|
||||
self.disposed = YES;
|
||||
for (BFCancellationTokenRegistration *registration in self.registrations) {
|
||||
[registration dispose];
|
||||
}
|
||||
[self.registrations removeAllObjects];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,3 +140,5 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -12,10 +12,12 @@
|
||||
|
||||
#import "BFCancellationToken.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface BFCancellationTokenRegistration ()
|
||||
|
||||
@property (nonatomic, weak) BFCancellationToken *token;
|
||||
@property (nonatomic, strong) BFCancellationBlock cancellationObserverBlock;
|
||||
@property (nullable, nonatomic, strong) BFCancellationBlock cancellationObserverBlock;
|
||||
@property (nonatomic, strong) NSObject *lock;
|
||||
@property (nonatomic) BOOL disposed;
|
||||
|
||||
@@ -38,7 +40,7 @@
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
if (!self) return self;
|
||||
|
||||
_lock = [NSObject new];
|
||||
|
||||
@@ -73,3 +75,5 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+5
-1
@@ -12,6 +12,8 @@
|
||||
|
||||
#import "BFCancellationToken.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface BFCancellationToken (BFCancellationTokenSource)
|
||||
|
||||
- (void)cancel;
|
||||
@@ -28,7 +30,7 @@
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
if (!self) return self;
|
||||
|
||||
_token = [BFCancellationToken new];
|
||||
|
||||
@@ -58,3 +60,5 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+6
-2
@@ -12,6 +12,8 @@
|
||||
|
||||
#import <pthread.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*!
|
||||
Get the remaining stack-size of the current thread.
|
||||
|
||||
@@ -22,7 +24,7 @@
|
||||
@note This function cannot be inlined, as otherwise the internal implementation could fail to report the proper
|
||||
remaining stack space.
|
||||
*/
|
||||
__attribute__((noinline)) static size_t remaining_stack_size(size_t *__nonnull restrict totalSize) {
|
||||
__attribute__((noinline)) static size_t remaining_stack_size(size_t *restrict totalSize) {
|
||||
pthread_t currentThread = pthread_self();
|
||||
|
||||
// NOTE: We must store stack pointers as uint8_t so that the pointer math is well-defined
|
||||
@@ -116,7 +118,7 @@ __attribute__((noinline)) static size_t remaining_stack_size(size_t *__nonnull r
|
||||
|
||||
- (instancetype)initWithBlock:(void(^)(void(^block)()))block {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
if (!self) return self;
|
||||
|
||||
_block = block;
|
||||
|
||||
@@ -130,3 +132,5 @@ __attribute__((noinline)) static size_t remaining_stack_size(size_t *__nonnull r
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
Generated
+20
@@ -29,6 +29,18 @@ extern NSInteger const kBFMultipleErrorsError;
|
||||
*/
|
||||
extern NSString *const BFTaskMultipleExceptionsException;
|
||||
|
||||
/*!
|
||||
An error userInfo key used if there were multiple errors on <BFTask taskForCompletionOfAllTasks:>.
|
||||
Value type is `NSArray<NSError *> *`.
|
||||
*/
|
||||
extern NSString *const BFTaskMultipleErrorsUserInfoKey;
|
||||
|
||||
/*!
|
||||
An error userInfo key used if there were multiple exceptions on <BFTask taskForCompletionOfAllTasks:>.
|
||||
Value type is `NSArray<NSException *> *`.
|
||||
*/
|
||||
extern NSString *const BFTaskMultipleExceptionsUserInfoKey;
|
||||
|
||||
@class BFExecutor;
|
||||
@class BFTask;
|
||||
|
||||
@@ -82,6 +94,14 @@ typedef __nullable id(^BFContinuationBlock)(BFTask<ResultType> *task);
|
||||
*/
|
||||
+ (instancetype)taskForCompletionOfAllTasksWithResults:(nullable NSArray<BFTask *> *)tasks;
|
||||
|
||||
/*!
|
||||
Returns a task that will be completed once there is at least one successful task.
|
||||
The first task to successuly complete will set the result, all other tasks results are
|
||||
ignored.
|
||||
@param tasks An `NSArray` of the tasks to use as an input.
|
||||
*/
|
||||
+ (instancetype)taskForCompletionOfAnyTask:(nullable NSArray<BFTask *> *)tasks;
|
||||
|
||||
/*!
|
||||
Returns a task that will be completed a certain amount of time in the future.
|
||||
@param millis The approximate number of milliseconds to wait before the
|
||||
|
||||
Generated
+131
-68
@@ -14,6 +14,8 @@
|
||||
|
||||
#import "Bolts.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__attribute__ ((noinline)) void warnBlockingOperationOnMainThread() {
|
||||
NSLog(@"Warning: A long-running operation is being executed on the main thread. \n"
|
||||
" Break on warnBlockingOperationOnMainThread() to debug.");
|
||||
@@ -23,6 +25,9 @@ NSString *const BFTaskErrorDomain = @"bolts";
|
||||
NSInteger const kBFMultipleErrorsError = 80175001;
|
||||
NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsException";
|
||||
|
||||
NSString *const BFTaskMultipleErrorsUserInfoKey = @"errors";
|
||||
NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions";
|
||||
|
||||
@interface BFTask () {
|
||||
id _result;
|
||||
NSError *_error;
|
||||
@@ -45,7 +50,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
if (!self) return self;
|
||||
|
||||
_lock = [[NSObject alloc] init];
|
||||
_condition = [[NSCondition alloc] init];
|
||||
@@ -56,7 +61,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
|
||||
- (instancetype)initWithResult:(id)result {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
if (!self) return self;
|
||||
|
||||
[self trySetResult:result];
|
||||
|
||||
@@ -65,7 +70,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
|
||||
- (instancetype)initWithError:(NSError *)error {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
if (!self) return self;
|
||||
|
||||
[self trySetError:error];
|
||||
|
||||
@@ -74,7 +79,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
|
||||
- (instancetype)initWithException:(NSException *)exception {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
if (!self) return self;
|
||||
|
||||
[self trySetException:exception];
|
||||
|
||||
@@ -83,7 +88,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
|
||||
- (instancetype)initCancelled {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
if (!self) return self;
|
||||
|
||||
[self trySetCancelled];
|
||||
|
||||
@@ -92,7 +97,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
|
||||
#pragma mark - Task Class methods
|
||||
|
||||
+ (instancetype)taskWithResult:(id)result {
|
||||
+ (instancetype)taskWithResult:(nullable id)result {
|
||||
return [[self alloc] initWithResult:result];
|
||||
}
|
||||
|
||||
@@ -108,7 +113,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
return [[self alloc] initCancelled];
|
||||
}
|
||||
|
||||
+ (instancetype)taskForCompletionOfAllTasks:(NSArray<BFTask *> *)tasks {
|
||||
+ (instancetype)taskForCompletionOfAllTasks:(nullable NSArray<BFTask *> *)tasks {
|
||||
__block int32_t total = (int32_t)tasks.count;
|
||||
if (total == 0) {
|
||||
return [self taskWithResult:nil];
|
||||
@@ -131,10 +136,10 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
[errors addObject:task.error];
|
||||
}
|
||||
} else if (task.cancelled) {
|
||||
OSAtomicIncrement32(&cancelled);
|
||||
OSAtomicIncrement32Barrier(&cancelled);
|
||||
}
|
||||
|
||||
if (OSAtomicDecrement32(&total) == 0) {
|
||||
if (OSAtomicDecrement32Barrier(&total) == 0) {
|
||||
if (exceptions.count > 0) {
|
||||
if (exceptions.count == 1) {
|
||||
tcs.exception = [exceptions firstObject];
|
||||
@@ -142,7 +147,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
NSException *exception =
|
||||
[NSException exceptionWithName:BFTaskMultipleExceptionsException
|
||||
reason:@"There were multiple exceptions."
|
||||
userInfo:@{ @"exceptions": exceptions }];
|
||||
userInfo:@{ BFTaskMultipleExceptionsUserInfoKey: exceptions }];
|
||||
tcs.exception = exception;
|
||||
}
|
||||
} else if (errors.count > 0) {
|
||||
@@ -151,7 +156,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
} else {
|
||||
NSError *error = [NSError errorWithDomain:BFTaskErrorDomain
|
||||
code:kBFMultipleErrorsError
|
||||
userInfo:@{ @"errors": errors }];
|
||||
userInfo:@{ BFTaskMultipleErrorsUserInfoKey: errors }];
|
||||
tcs.error = error;
|
||||
}
|
||||
} else if (cancelled > 0) {
|
||||
@@ -166,12 +171,78 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
return tcs.task;
|
||||
}
|
||||
|
||||
+ (instancetype)taskForCompletionOfAllTasksWithResults:(NSArray<BFTask *> *)tasks {
|
||||
+ (instancetype)taskForCompletionOfAllTasksWithResults:(nullable NSArray<BFTask *> *)tasks {
|
||||
return [[self taskForCompletionOfAllTasks:tasks] continueWithSuccessBlock:^id(BFTask *task) {
|
||||
return [tasks valueForKey:@"result"];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (instancetype)taskForCompletionOfAnyTask:(nullable NSArray<BFTask *> *)tasks
|
||||
{
|
||||
__block int32_t total = (int32_t)tasks.count;
|
||||
if (total == 0) {
|
||||
return [self taskWithResult:nil];
|
||||
}
|
||||
|
||||
__block int completed = 0;
|
||||
__block int32_t cancelled = 0;
|
||||
|
||||
NSObject *lock = [NSObject new];
|
||||
NSMutableArray<NSError *> *errors = [NSMutableArray new];
|
||||
NSMutableArray<NSException *> *exceptions = [NSMutableArray new];
|
||||
|
||||
BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource];
|
||||
for (BFTask *task in tasks) {
|
||||
[task continueWithBlock:^id(BFTask *task) {
|
||||
if (task.exception != nil) {
|
||||
@synchronized(lock) {
|
||||
[exceptions addObject:task.exception];
|
||||
}
|
||||
} else if (task.error != nil) {
|
||||
@synchronized(lock) {
|
||||
[errors addObject:task.error];
|
||||
}
|
||||
} else if (task.cancelled) {
|
||||
OSAtomicIncrement32Barrier(&cancelled);
|
||||
} else {
|
||||
if(OSAtomicCompareAndSwap32Barrier(0, 1, &completed)) {
|
||||
[source setResult:task.result];
|
||||
}
|
||||
}
|
||||
|
||||
if (OSAtomicDecrement32Barrier(&total) == 0 &&
|
||||
OSAtomicCompareAndSwap32Barrier(0, 1, &completed)) {
|
||||
if (cancelled > 0) {
|
||||
[source cancel];
|
||||
} else if (exceptions.count > 0) {
|
||||
if (exceptions.count == 1) {
|
||||
source.exception = exceptions.firstObject;
|
||||
} else {
|
||||
NSException *exception =
|
||||
[NSException exceptionWithName:BFTaskMultipleExceptionsException
|
||||
reason:@"There were multiple exceptions."
|
||||
userInfo:@{ @"exceptions": exceptions }];
|
||||
source.exception = exception;
|
||||
}
|
||||
} else if (errors.count > 0) {
|
||||
if (errors.count == 1) {
|
||||
source.error = errors.firstObject;
|
||||
} else {
|
||||
NSError *error = [NSError errorWithDomain:BFTaskErrorDomain
|
||||
code:kBFMultipleErrorsError
|
||||
userInfo:@{ @"errors": errors }];
|
||||
source.error = error;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Abort execution of per tasks continuations
|
||||
return nil;
|
||||
}];
|
||||
}
|
||||
return source.task;
|
||||
}
|
||||
|
||||
|
||||
+ (instancetype)taskWithDelay:(int)millis {
|
||||
BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource];
|
||||
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, millis * NSEC_PER_MSEC);
|
||||
@@ -181,8 +252,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
return tcs.task;
|
||||
}
|
||||
|
||||
+ (instancetype)taskWithDelay:(int)millis
|
||||
cancellationToken:(BFCancellationToken *)token {
|
||||
+ (instancetype)taskWithDelay:(int)millis cancellationToken:(nullable BFCancellationToken *)token {
|
||||
if (token.cancellationRequested) {
|
||||
return [BFTask cancelledTask];
|
||||
}
|
||||
@@ -207,13 +277,13 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
|
||||
#pragma mark - Custom Setters/Getters
|
||||
|
||||
- (id)result {
|
||||
- (nullable id)result {
|
||||
@synchronized(self.lock) {
|
||||
return _result;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)trySetResult:(id)result {
|
||||
- (BOOL)trySetResult:(nullable id)result {
|
||||
@synchronized(self.lock) {
|
||||
if (self.completed) {
|
||||
return NO;
|
||||
@@ -225,7 +295,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
}
|
||||
}
|
||||
|
||||
- (NSError *)error {
|
||||
- (nullable NSError *)error {
|
||||
@synchronized(self.lock) {
|
||||
return _error;
|
||||
}
|
||||
@@ -244,7 +314,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
}
|
||||
}
|
||||
|
||||
- (NSException *)exception {
|
||||
- (nullable NSException *)exception {
|
||||
@synchronized(self.lock) {
|
||||
return _exception;
|
||||
}
|
||||
@@ -293,12 +363,6 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setCompleted {
|
||||
@synchronized(self.lock) {
|
||||
_completed = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)runContinuations {
|
||||
@synchronized(self.lock) {
|
||||
[self.condition lock];
|
||||
@@ -313,70 +377,69 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
|
||||
#pragma mark - Chaining methods
|
||||
|
||||
- (BFTask *)continueWithExecutor:(BFExecutor *)executor
|
||||
withBlock:(BFContinuationBlock)block {
|
||||
- (BFTask *)continueWithExecutor:(BFExecutor *)executor withBlock:(BFContinuationBlock)block {
|
||||
return [self continueWithExecutor:executor block:block cancellationToken:nil];
|
||||
}
|
||||
|
||||
- (BFTask *)continueWithExecutor:(BFExecutor *)executor
|
||||
block:(BFContinuationBlock)block
|
||||
cancellationToken:(BFCancellationToken *)cancellationToken {
|
||||
cancellationToken:(nullable BFCancellationToken *)cancellationToken {
|
||||
BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource];
|
||||
|
||||
// Capture all of the state that needs to used when the continuation is complete.
|
||||
void (^wrappedBlock)() = ^() {
|
||||
[executor execute:^{
|
||||
if (cancellationToken.cancellationRequested) {
|
||||
[tcs cancel];
|
||||
return;
|
||||
}
|
||||
dispatch_block_t executionBlock = ^{
|
||||
if (cancellationToken.cancellationRequested) {
|
||||
[tcs cancel];
|
||||
return;
|
||||
}
|
||||
|
||||
id result = nil;
|
||||
@try {
|
||||
result = block(self);
|
||||
} @catch (NSException *exception) {
|
||||
tcs.exception = exception;
|
||||
return;
|
||||
}
|
||||
id result = nil;
|
||||
@try {
|
||||
result = block(self);
|
||||
} @catch (NSException *exception) {
|
||||
tcs.exception = exception;
|
||||
return;
|
||||
}
|
||||
|
||||
if ([result isKindOfClass:[BFTask class]]) {
|
||||
if ([result isKindOfClass:[BFTask class]]) {
|
||||
|
||||
id (^setupWithTask) (BFTask *) = ^id(BFTask *task) {
|
||||
if (cancellationToken.cancellationRequested || task.cancelled) {
|
||||
[tcs cancel];
|
||||
} else if (task.exception) {
|
||||
tcs.exception = task.exception;
|
||||
} else if (task.error) {
|
||||
tcs.error = task.error;
|
||||
} else {
|
||||
tcs.result = task.result;
|
||||
}
|
||||
return nil;
|
||||
};
|
||||
|
||||
BFTask *resultTask = (BFTask *)result;
|
||||
|
||||
if (resultTask.completed) {
|
||||
setupWithTask(resultTask);
|
||||
id (^setupWithTask) (BFTask *) = ^id(BFTask *task) {
|
||||
if (cancellationToken.cancellationRequested || task.cancelled) {
|
||||
[tcs cancel];
|
||||
} else if (task.exception) {
|
||||
tcs.exception = task.exception;
|
||||
} else if (task.error) {
|
||||
tcs.error = task.error;
|
||||
} else {
|
||||
[resultTask continueWithBlock:setupWithTask];
|
||||
tcs.result = task.result;
|
||||
}
|
||||
return nil;
|
||||
};
|
||||
|
||||
BFTask *resultTask = (BFTask *)result;
|
||||
|
||||
if (resultTask.completed) {
|
||||
setupWithTask(resultTask);
|
||||
} else {
|
||||
tcs.result = result;
|
||||
[resultTask continueWithBlock:setupWithTask];
|
||||
}
|
||||
}];
|
||||
|
||||
} else {
|
||||
tcs.result = result;
|
||||
}
|
||||
};
|
||||
|
||||
BOOL completed;
|
||||
@synchronized(self.lock) {
|
||||
completed = self.completed;
|
||||
if (!completed) {
|
||||
[self.callbacks addObject:[wrappedBlock copy]];
|
||||
[self.callbacks addObject:[^{
|
||||
[executor execute:executionBlock];
|
||||
} copy]];
|
||||
}
|
||||
}
|
||||
if (completed) {
|
||||
wrappedBlock();
|
||||
[executor execute:executionBlock];
|
||||
}
|
||||
|
||||
return tcs.task;
|
||||
@@ -386,8 +449,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
return [self continueWithExecutor:[BFExecutor defaultExecutor] block:block cancellationToken:nil];
|
||||
}
|
||||
|
||||
- (BFTask *)continueWithBlock:(BFContinuationBlock)block
|
||||
cancellationToken:(BFCancellationToken *)cancellationToken {
|
||||
- (BFTask *)continueWithBlock:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken {
|
||||
return [self continueWithExecutor:[BFExecutor defaultExecutor] block:block cancellationToken:cancellationToken];
|
||||
}
|
||||
|
||||
@@ -398,7 +460,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
|
||||
- (BFTask *)continueWithExecutor:(BFExecutor *)executor
|
||||
successBlock:(BFContinuationBlock)block
|
||||
cancellationToken:(BFCancellationToken *)cancellationToken {
|
||||
cancellationToken:(nullable BFCancellationToken *)cancellationToken {
|
||||
if (cancellationToken.cancellationRequested) {
|
||||
return [BFTask cancelledTask];
|
||||
}
|
||||
@@ -416,8 +478,7 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
return [self continueWithExecutor:[BFExecutor defaultExecutor] successBlock:block cancellationToken:nil];
|
||||
}
|
||||
|
||||
- (BFTask *)continueWithSuccessBlock:(BFContinuationBlock)block
|
||||
cancellationToken:(BFCancellationToken *)cancellationToken {
|
||||
- (BFTask *)continueWithSuccessBlock:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken {
|
||||
return [self continueWithExecutor:[BFExecutor defaultExecutor] successBlock:block cancellationToken:cancellationToken];
|
||||
}
|
||||
|
||||
@@ -470,3 +531,5 @@ NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsExcept
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+7
-9
@@ -12,15 +12,11 @@
|
||||
|
||||
#import "BFTask.h"
|
||||
|
||||
@interface BFTaskCompletionSource ()
|
||||
|
||||
@property (nonatomic, strong, readwrite) BFTask *task;
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface BFTask (BFTaskCompletionSource)
|
||||
|
||||
- (BOOL)trySetResult:(id)result;
|
||||
- (BOOL)trySetResult:(nullable id)result;
|
||||
- (BOOL)trySetError:(NSError *)error;
|
||||
- (BOOL)trySetException:(NSException *)exception;
|
||||
- (BOOL)trySetCancelled;
|
||||
@@ -37,7 +33,7 @@
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (!self) return nil;
|
||||
if (!self) return self;
|
||||
|
||||
_task = [[BFTask alloc] init];
|
||||
|
||||
@@ -46,7 +42,7 @@
|
||||
|
||||
#pragma mark - Custom Setters/Getters
|
||||
|
||||
- (void)setResult:(id)result {
|
||||
- (void)setResult:(nullable id)result {
|
||||
if (![self.task trySetResult:result]) {
|
||||
[NSException raise:NSInternalInconsistencyException
|
||||
format:@"Cannot set the result on a completed task."];
|
||||
@@ -74,7 +70,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)trySetResult:(id)result {
|
||||
- (BOOL)trySetResult:(nullable id)result {
|
||||
return [self.task trySetResult:result];
|
||||
}
|
||||
|
||||
@@ -91,3 +87,5 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
Generated
+4
-9
@@ -8,7 +8,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#import <Bolts/BoltsVersion.h>
|
||||
#import <Bolts/BFCancellationToken.h>
|
||||
#import <Bolts/BFCancellationTokenRegistration.h>
|
||||
#import <Bolts/BFCancellationTokenSource.h>
|
||||
@@ -28,16 +27,12 @@
|
||||
#import <Bolts/BFWebViewAppLinkResolver.h>
|
||||
#endif
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface Bolts : NSObject
|
||||
|
||||
/*!
|
||||
Returns the version of the Bolts Framework as an NSString.
|
||||
@returns The NSString representation of the current version.
|
||||
/**
|
||||
A string containing the version of the Bolts Framework used by the current application.
|
||||
*/
|
||||
+ (NSString *)version;
|
||||
|
||||
@end
|
||||
extern NSString *const BoltsFrameworkVersionString;
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
Generated
+3
-5
@@ -10,10 +10,8 @@
|
||||
|
||||
#import "Bolts.h"
|
||||
|
||||
@implementation Bolts
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
+ (NSString *)version {
|
||||
return BOLTS_VERSION;
|
||||
}
|
||||
NSString *const BoltsFrameworkVersionString = @"1.7.0";
|
||||
|
||||
@end
|
||||
NS_ASSUME_NONNULL_END
|
||||
-1
@@ -1 +0,0 @@
|
||||
#define BOLTS_VERSION @"1.6.0"
|
||||
+3
-8
@@ -10,13 +10,8 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "BFAppLinkNavigation.h"
|
||||
#import "BFTaskCompletionSource.h"
|
||||
#import "BFAppLinkTarget.h"
|
||||
#import "BoltsVersion.h"
|
||||
#import "BFWebViewAppLinkResolver.h"
|
||||
#import "BFExecutor.h"
|
||||
#import "BFTask.h"
|
||||
#import <Bolts/Bolts.h>
|
||||
|
||||
#import "BFMeasurementEvent_Internal.h"
|
||||
#import "BFAppLink_Internal.h"
|
||||
|
||||
@@ -65,7 +60,7 @@ static id<BFAppLinkResolving> defaultResolver;
|
||||
|
||||
// Add applink protocol data
|
||||
if (!appLinkData[BFAppLinkUserAgentKeyName]) {
|
||||
appLinkData[BFAppLinkUserAgentKeyName] = [NSString stringWithFormat:@"Bolts iOS %@", BOLTS_VERSION];
|
||||
appLinkData[BFAppLinkUserAgentKeyName] = [NSString stringWithFormat:@"Bolts iOS %@", BoltsFrameworkVersionString];
|
||||
}
|
||||
if (!appLinkData[BFAppLinkVersionKeyName]) {
|
||||
appLinkData[BFAppLinkVersionKeyName] = BFAppLinkVersion;
|
||||
|
||||
@@ -27,7 +27,6 @@ static const CGFloat BFCloseButtonHeight = 12.0;
|
||||
@property (nonatomic, strong) UILabel *labelView;
|
||||
@property (nonatomic, strong) UIButton *closeButton;
|
||||
@property (nonatomic, strong) UITapGestureRecognizer *insideTapGestureRecognizer;
|
||||
@property (nonatomic, strong) UIView *viewToMoveWithNavController;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -248,6 +248,9 @@ static NSString *const BFWebViewAppLinkResolverShouldFallbackKey = @"should_fall
|
||||
break;
|
||||
#ifdef __TVOS_9_0
|
||||
case UIUserInterfaceIdiomTV:
|
||||
#endif
|
||||
#ifdef __IPHONE_9_3
|
||||
case UIUserInterfaceIdiomCarPlay:
|
||||
#endif
|
||||
case UIUserInterfaceIdiomUnspecified:
|
||||
default:
|
||||
|
||||
Generated
+14
-13
@@ -1,13 +1,14 @@
|
||||
Bolts
|
||||
============
|
||||
[](https://travis-ci.org/BoltsFramework/Bolts-iOS)
|
||||
[](https://codecov.io/github/BoltsFramework/Bolts-iOS?branch=master)
|
||||
[](https://github.com/Carthage/Carthage)
|
||||
[](http://cocoadocs.org/docsets/Bolts/)
|
||||
[](http://cocoadocs.org/docsets/Bolts/)
|
||||
[](https://github.com/BoltsFramework/Bolts-iOS/blob/master/LICENSE)
|
||||
[](https://travis-ci.org/BoltsFramework/Bolts-ObjC)
|
||||
[](https://codecov.io/github/BoltsFramework/Bolts-ObjC?branch=master)
|
||||
[](https://cocoapods.org/pods/Bolts)
|
||||
[](https://github.com/BoltsFramework/Bolts-ObjC/blob/master/LICENSE)
|
||||
[](https://www.versioneye.com/objective-c/bolts/references)
|
||||
|
||||
[](https://cocoapods.org/pods/Bolts)
|
||||
[](https://github.com/Carthage/Carthage)
|
||||
|
||||
Bolts is a collection of low-level libraries designed to make developing mobile
|
||||
apps easier. Bolts was designed by Parse and Facebook for our own internal use,
|
||||
and we have decided to open source these libraries to make them available to
|
||||
@@ -17,7 +18,7 @@ do they require having a Parse or Facebook developer account.
|
||||
Bolts includes:
|
||||
|
||||
* "Tasks", which make organization of complex asynchronous code more manageable. A task is kind of like a JavaScript Promise, but available for iOS and Android.
|
||||
* An implementation of the [App Links protocol](http://www.applinks.org), helping you link to content in other apps and handle incoming deep-links.
|
||||
* An implementation of the [App Links protocol](http://applinks.org/), helping you link to content in other apps and handle incoming deep-links.
|
||||
|
||||
For more information, see the [Bolts iOS API Reference](http://boltsframework.github.io/docs/ios/).
|
||||
|
||||
@@ -59,7 +60,7 @@ self.saveAsync(obj).continueWithBlock {
|
||||
(task: BFTask!) -> BFTask in
|
||||
if task.isCancelled() {
|
||||
// the save was cancelled.
|
||||
} else if task.error() {
|
||||
} else if task.error != nil {
|
||||
// the save failed.
|
||||
} else {
|
||||
// the object was saved successfully.
|
||||
@@ -237,7 +238,7 @@ findAsync(query).continueWithSuccessBlock {
|
||||
return self.findAsync(query)
|
||||
}.continueWithBlock {
|
||||
(task: BFTask!) -> AnyObject! in
|
||||
if task.error() {
|
||||
if task.error != nil {
|
||||
// This error handler WILL be called.
|
||||
// The error will be the NSError returned above.
|
||||
// Let's handle the error by returning a new value.
|
||||
@@ -503,7 +504,7 @@ We are likely to add some concept like this to Bolts at some point in the future
|
||||
|
||||
# App Links
|
||||
|
||||
[App Links](http://www.applinks.org) provide a cross-platform mechanism that allows a developer to define and publish a deep-linking scheme for their content, allowing other apps to link directly to an experience optimized for the device they are running on. Whether you are building an app that receives incoming links or one that may link out to other apps' content, Bolts provides tools to simplify implementation of the [App Links protocol](http://www.applinks.org/documentation).
|
||||
[App Links](http://applinks.org/) provide a cross-platform mechanism that allows a developer to define and publish a deep-linking scheme for their content, allowing other apps to link directly to an experience optimized for the device they are running on. Whether you are building an app that receives incoming links or one that may link out to other apps' content, Bolts provides tools to simplify implementation of the [App Links protocol](http://applinks.org/documentation).
|
||||
|
||||
## Handling an App Link
|
||||
|
||||
@@ -629,7 +630,7 @@ The following code assumes that the view controller has an `openedAppLinkURL` `N
|
||||
}
|
||||
```
|
||||
|
||||
In a navigaton-controller view hierarchy, the banner should be displayed above the navigation bar, and `BFAppLinkReturnToRefererController` provides an `initForDisplayAboveNavController` method to assist with this.
|
||||
In a navigation-controller view hierarchy, the banner should be displayed above the navigation bar, and `BFAppLinkReturnToRefererController` provides an `initForDisplayAboveNavController` method to assist with this.
|
||||
|
||||
## Analytics
|
||||
|
||||
@@ -675,8 +676,8 @@ App Links Measurement Events sends additional information from App Links Intents
|
||||
|
||||
# Installation
|
||||
|
||||
You can download the latest framework files from our [Releases page](https://github.com/BoltsFramework/Bolts-iOS/releases).
|
||||
You can download the latest framework files from our [Releases page](https://github.com/BoltsFramework/Bolts-ObjC/releases).
|
||||
|
||||
Bolts is also available through [CocoaPods](http://cocoapods.org). To install it simply add the following line to your Podfile:
|
||||
Bolts is also available through [CocoaPods](https://cocoapods.org/). To install it simply add the following line to your Podfile:
|
||||
|
||||
pod 'Bolts'
|
||||
Reference in new issue
Block a user