Skip to content

Commit

Permalink
Merge pull request #35 from grigaci/baseOperation
Browse files Browse the repository at this point in the history
Add base operation
  • Loading branch information
grigaci committed May 31, 2016
2 parents 293e7a7 + a90d179 commit e6a73f0
Show file tree
Hide file tree
Showing 7 changed files with 363 additions and 26 deletions.
20 changes: 20 additions & 0 deletions BIObjCHelpers.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
/* Begin PBXBuildFile section */
431124921CE36CDC00950918 /* BIOperationNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 431124901CE36CDC00950918 /* BIOperationNotifier.h */; settings = {ATTRIBUTES = (Public, ); }; };
431124931CE36CDC00950918 /* BIOperationNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 431124911CE36CDC00950918 /* BIOperationNotifier.m */; };
43A5B5531CFD6EF900F79359 /* BIOperationBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 43A5B5511CFD6EF900F79359 /* BIOperationBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
43A5B5541CFD6EF900F79359 /* BIOperationBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A5B5521CFD6EF900F79359 /* BIOperationBase.m */; };
43A5B5571CFD733300F79359 /* BIOperationBaseTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A5B5561CFD733300F79359 /* BIOperationBaseTestCase.m */; };
43F541CD1CD0F276002EB6C6 /* BIObjCHelpers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43F541C31CD0F275002EB6C6 /* BIObjCHelpers.framework */; };
43F541DC1CD0F2AD002EB6C6 /* _BIScrollViewProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 91614A821B94790400D00EB2 /* _BIScrollViewProxy.m */; };
43F541DE1CD0F2AD002EB6C6 /* UIScrollView+BIBatching.m in Sources */ = {isa = PBXBuildFile; fileRef = 432001971C7B26C0006A8BB7 /* UIScrollView+BIBatching.m */; };
Expand Down Expand Up @@ -142,6 +145,9 @@
4355334F1B81B87F0052A128 /* _BITableView+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "_BITableView+Internal.h"; path = "Views/TableView/_BITableView+Internal.h"; sourceTree = "<group>"; };
435D59BE1B622E8A00ECA859 /* BIMockHandlerTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BIMockHandlerTableView.h; path = BIHandlerTableView/BIMockHandlerTableView.h; sourceTree = "<group>"; };
435D59BF1B622E8A00ECA859 /* BIMockHandlerTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BIMockHandlerTableView.m; path = BIHandlerTableView/BIMockHandlerTableView.m; sourceTree = "<group>"; };
43A5B5511CFD6EF900F79359 /* BIOperationBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BIOperationBase.h; path = Operations/BIOperationBase.h; sourceTree = "<group>"; };
43A5B5521CFD6EF900F79359 /* BIOperationBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BIOperationBase.m; path = Operations/BIOperationBase.m; sourceTree = "<group>"; };
43A5B5561CFD733300F79359 /* BIOperationBaseTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BIOperationBaseTestCase.m; path = Operations/BIOperationBaseTestCase.m; sourceTree = "<group>"; };
43A7D0251C735C1B007C8CC0 /* LICENSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.txt; sourceTree = "<group>"; };
43A7D0261C735C1B007C8CC0 /* UIScrollView+InfiniteScroll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+InfiniteScroll.h"; sourceTree = "<group>"; };
43A7D0271C735C1B007C8CC0 /* UIScrollView+InfiniteScroll.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+InfiniteScroll.m"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -283,6 +289,8 @@
4311248D1CE36CA200950918 /* Operations */ = {
isa = PBXGroup;
children = (
43A5B5511CFD6EF900F79359 /* BIOperationBase.h */,
43A5B5521CFD6EF900F79359 /* BIOperationBase.m */,
431124901CE36CDC00950918 /* BIOperationNotifier.h */,
431124911CE36CDC00950918 /* BIOperationNotifier.m */,
);
Expand Down Expand Up @@ -322,6 +330,14 @@
name = BIHandlerTableView;
sourceTree = "<group>";
};
43A5B5551CFD731B00F79359 /* Operations */ = {
isa = PBXGroup;
children = (
43A5B5561CFD733300F79359 /* BIOperationBaseTestCase.m */,
);
name = Operations;
sourceTree = "<group>";
};
43A7D01E1C7349DA007C8CC0 /* ExternalLibs */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -563,6 +579,7 @@
43BE6CDF1B568ECB001F0A00 /* Datasource */,
43BE6CEA1B568ECB001F0A00 /* Handler */,
43BE6CED1B568ECB001F0A00 /* Lifecycle */,
43A5B5551CFD731B00F79359 /* Operations */,
43BE6CEF1B568ECB001F0A00 /* OperationQueue */,
43BE6CF21B568ECB001F0A00 /* Starters */,
);
Expand Down Expand Up @@ -954,6 +971,7 @@
43F542341CD0F417002EB6C6 /* NSDate+BIAttributedString.h in Headers */,
43F5423C1CD0F429002EB6C6 /* BIDatasourceTableView.h in Headers */,
43F542381CD0F424002EB6C6 /* BIDatasourceFetchedCollectionView.h in Headers */,
43A5B5531CFD6EF900F79359 /* BIOperationBase.h in Headers */,
43F542351CD0F41A002EB6C6 /* NSString+BIExtra.h in Headers */,
43F5422C1CD0F393002EB6C6 /* BITableViewCell.h in Headers */,
43F542361CD0F422002EB6C6 /* BIDatasourceBase.h in Headers */,
Expand Down Expand Up @@ -1190,6 +1208,7 @@
43F5421E1CD0F2AE002EB6C6 /* BIStartersFactory.m in Sources */,
43F542201CD0F2AE002EB6C6 /* BILaunchStartersFactory.m in Sources */,
43F542231CD0F2AE002EB6C6 /* UIScrollView+InfiniteScroll.m in Sources */,
43A5B5541CFD6EF900F79359 /* BIOperationBase.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -1200,6 +1219,7 @@
43FA5D5E1CD2325200FA754E /* BIDatasourceTableViewTestCase.m in Sources */,
43FA5D611CD2325B00FA754E /* BIMockDatasourceFeedTableView.m in Sources */,
43FA5D651CD2326A00FA754E /* BIOperationQueueTestCase.m in Sources */,
43A5B5571CFD733300F79359 /* BIOperationBaseTestCase.m in Sources */,
43FA5D541CD2321E00FA754E /* BITableViewTestCase.m in Sources */,
43FA5D521CD2321900FA754E /* BIActivityIndicatorContainerViewTestCase.m in Sources */,
43FA5D661CD2326F00FA754E /* BIStartersFactoryTestCase.m in Sources */,
Expand Down
36 changes: 36 additions & 0 deletions BIObjCHelpers/Operations/BIOperationBase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// BIOperationBase.h
// BIObjCHelpers
//
// Created by Bogdan Iusco on 5/31/16.
// Copyright © 2016 iGama Apps. All rights reserved.
//

#import <Foundation/Foundation.h>

extern void dispatchCodeOnMainThread(void(^__nonnull codeBlock)());

@interface BIOperationBase : NSOperation

// NSOperation
@property (nonatomic, assign, readonly) BOOL isExecuting;
@property (nonatomic, assign, readonly) BOOL isFinished;

// Callbacks
@property (nonatomic, copy, nullable) void(^didFinishWithErrorCallback)(NSError *__nonnull error);
@property (nonatomic, copy, nullable) void(^didFinishSuccessfullyCallback)(id __nonnull responseObject);
@property (nonatomic, copy, nullable) void(^didFinishCommonCallback)();
@property (nonatomic, assign) BOOL runCallbacksOnMainThread;

// Handle operations response states
- (void)handleDidFinishedWithResponse:(nonnull id)response;
- (void)handleDidFinishedWithError:(nonnull NSError *)error;
- (void)handleDidFinishedCommon;
- (void)finish;

// Trigger callbacks
- (void)safeCallDidFinishWithErrorCallback:(nonnull NSError *)error;
- (void)safeCallDidFinishSuccessfullyCallback:(nonnull id)responseObject;
- (void)safeCallDidFinishCommon;

@end
116 changes: 116 additions & 0 deletions BIObjCHelpers/Operations/BIOperationBase.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
//
// BIOperationBase.m
// BIObjCHelpers
//
// Created by Bogdan Iusco on 5/31/16.
// Copyright © 2016 iGama Apps. All rights reserved.
//

#import "BIOperationBase.h"

void dispatchCodeOnMainThread(void(^__nonnull codeBlock)()) {
if (![NSThread isMainThread]) {
dispatch_async(dispatch_get_main_queue(), ^{
codeBlock();
});
} else {
codeBlock();
}
}

@implementation BIOperationBase

#pragma mark - Init methods

- (nonnull instancetype)init {
self = [super init];
if (self) {
self.runCallbacksOnMainThread = YES;
}
return self;
}

#pragma mark - NSOperation methods

- (void)start {
dispatchCodeOnMainThread( ^{
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];
});
}

#pragma mark - Public methods

- (void)safeCallDidFinishWithErrorCallback:(nonnull NSError *)error {
void(^block)() = ^{
if (self.didFinishWithErrorCallback) {
self.didFinishWithErrorCallback(error);
}
[self handleDidFinishedCommon];
};
if (self.runCallbacksOnMainThread) {
dispatchCodeOnMainThread( ^{
block();
});
} else {
block();
}
}

- (void)safeCallDidFinishSuccessfullyCallback:(nonnull id)responseObject {
void(^block)() = ^{
if (self.didFinishSuccessfullyCallback) {
self.didFinishSuccessfullyCallback(responseObject);
}
[self handleDidFinishedCommon];
};
if (self.runCallbacksOnMainThread) {
dispatchCodeOnMainThread( ^{
block();
});
} else {
block();
}
}

- (void)safeCallDidFinishCommon {
void(^block)() = ^{
if (self.didFinishCommonCallback) {
self.didFinishCommonCallback();
}
};
if (self.runCallbacksOnMainThread) {
dispatchCodeOnMainThread( ^{
block();
});
} else {
block();
}
}

- (void)handleDidFinishedWithResponse:(id)response {
[self safeCallDidFinishSuccessfullyCallback:response];
}

- (void)handleDidFinishedWithError:(NSError *)error {
[self safeCallDidFinishWithErrorCallback:error];
}

- (void)handleDidFinishedCommon {
[self safeCallDidFinishCommon];
[self finish];
}

- (void)finish {
dispatchCodeOnMainThread( ^{
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
_isExecuting = NO;
_isFinished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
});
}

@end
11 changes: 3 additions & 8 deletions BIObjCHelpers/Operations/BIOperationNotifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// Copyright © 2016 iGama Apps. All rights reserved.
//

#import <BIObjCHelpers/BIOperationBase.h>

#import <Foundation/Foundation.h>

@class BIOperationNotifier;
Expand All @@ -19,16 +21,9 @@

@end

@interface BIOperationNotifier : NSOperation

@property (nonatomic, copy, nullable) void(^didFinishWithErrorCallback)(NSError *__nonnull error);
@property (nonatomic, copy, nullable) void(^didFinishSuccessfullyCallback)(id __nonnull responseObject);
@property (nonatomic, copy, nullable) void(^didFinishCommonCallback)();
@interface BIOperationNotifier : BIOperationBase

- (void)registerOperationFinishedListener:(id<BIOperationNotifierListener> __nonnull)listener;
- (void)unregisterOperationFinishedListener:(id<BIOperationNotifierListener> __nonnull)listener;

- (void)safeCallDidFinishWithErrorCallback:(nonnull NSError *)error;
- (void)safeCallDidFinishSuccessfullyCallback:(nonnull id)responseObject;

@end
59 changes: 41 additions & 18 deletions BIObjCHelpers/Operations/BIOperationNotifier.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,57 @@ @interface BIOperationNotifier()

@implementation BIOperationNotifier

#pragma mark - Public methods

- (void)registerOperationFinishedListener:(id<BIOperationNotifierListener>)listener {
[self.operationFinishedListeners addObject:listener];
}

- (void)unregisterOperationFinishedListener:(id<BIOperationNotifierListener>)listener {
[self.operationFinishedListeners removeObject:listener];
}

#pragma mark - BIOperationBase methods

- (void)safeCallDidFinishWithErrorCallback:(nonnull NSError *)error {
dispatch_async(dispatch_get_main_queue(), ^{
void(^block)() = ^{
[self BI_notifyOperationDidFinishWithError:error];
[self safeCallDidFinishCommon];
});
[self handleDidFinishedCommon];
};
if (self.runCallbacksOnMainThread) {
dispatchCodeOnMainThread( ^{
block();
});
} else {
block();
}
}

- (void)safeCallDidFinishSuccessfullyCallback:(nonnull id)responseObject {
dispatch_async(dispatch_get_main_queue(), ^{
void(^block)() = ^{
[self BI_notifyOperationDidFinishWithResponse:responseObject];
[self safeCallDidFinishCommon];
});
[self handleDidFinishedCommon];
};
if (self.runCallbacksOnMainThread) {
dispatchCodeOnMainThread( ^{
block();
});
} else {
block();
}
}

- (void)safeCallDidFinishCommon {
dispatch_async(dispatch_get_main_queue(), ^{
void(^block)() = ^{
[self BI_notifyOperationDidFinishCommon];
});
}

#pragma mark - Public methods

- (void)registerOperationFinishedListener:(id<BIOperationNotifierListener>)listener {
[self.operationFinishedListeners addObject:listener];
}

- (void)unregisterOperationFinishedListener:(id<BIOperationNotifierListener>)listener {
[self.operationFinishedListeners removeObject:listener];
};
if (self.runCallbacksOnMainThread) {
dispatchCodeOnMainThread( ^{
block();
});
} else {
block();
}
}

#pragma mark - Properties methods
Expand Down
1 change: 1 addition & 0 deletions BIObjCHelpers/SupportingFiles/BIObjCHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ FOUNDATION_EXPORT const unsigned char BIObjCHelpersVersionString[];
#import <BIObjCHelpers/BIOperationQueue.h>
#import <BIObjCHelpers/BISerialOperationQueue.h>
#import <BIObjCHelpers/BIOperationNotifier.h>
#import <BIObjCHelpers/BIOperationBase.h>

// Views
#import <BIObjCHelpers/BITableView.h>
Expand Down
Loading

0 comments on commit e6a73f0

Please sign in to comment.