Skip to content

Instantly share code, notes, and snippets.

@chunkyguy
Created February 21, 2020 17:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chunkyguy/0f67f074c974aac7024d153011e5400e to your computer and use it in GitHub Desktop.
Save chunkyguy/0f67f074c974aac7024d153011e5400e to your computer and use it in GitHub Desktop.
Rx with ObjectiveC using NSInvocation
#import "RxObservable.h"
@interface RxArraySource : RxObservable
+ (instancetype)createWithElements: (NSArray *)array;
- (void)subscribe:(NSInvocation *)invocation;
@end
#import "RxArraySource.h"
@interface RxArraySource ()
@property (nonatomic, copy) NSArray *elements;
@end
@implementation RxArraySource
+ (instancetype)createWithElements:(NSArray *)elements;
{
RxArraySource *instance = [RxArraySource new];
instance.elements = elements;
return instance;
}
- (void)subscribe:(NSInvocation *)invocation;
{
for (id element in _elements) {
[invocation setArgument:&element atIndex:2];
[invocation invoke];
}
}
@end
@interface RxDriver : NSObject
- (void)run;
@end
#import "RxDriver.h"
#import "NSInvocation+RxConvenience.h"
#import "RxObservable.h"
@implementation RxDriver
- (void)print:(NSNumber *)num
{
NSLog(@"%@", num);
}
- (NSNumber *)tenTimesOfNumber:(NSNumber *)num
{
return [NSNumber numberWithInteger:[num integerValue] * 10];
}
- (void)run
{
NSInvocation *verbose = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(print:)]];
[verbose setTarget:self];
[verbose setSelector:@selector(print:)];
RxObservable *stream = [RxObservable observableFromArray:@[@1, @2, @3]];
// Simple subscribe
NSInvocation *printInvoc = [NSInvocation invocationWithTarget:self
selector:@selector(print:)];
[stream subscribe:printInvoc];
// Square
NSInvocation *mapInvoc = [NSInvocation invocationWithTarget:self
selector:@selector(tenTimesOfNumber:)];
[[stream mapWithInvocation:mapInvoc] subscribe:printInvoc];
}
@end
#import "RxObservable.h"
@interface RxMapOperator : RxObservable
+ (instancetype) operatorFromStream:(RxObservable *)upstream
withInvocation:(NSInvocation *)invoc;
@end
#import "RxMapOperator.h"
#import "NSInvocation+RxConvenience.h"
@interface RxMapOperator ()
@property (nonatomic, strong) RxObservable *stream;
@property (nonatomic, strong) NSInvocation *invocUp;
@property (nonatomic, strong) NSInvocation *invocDown;
@end
@implementation RxMapOperator
+ (instancetype) operatorFromStream:(RxObservable *)stream
withInvocation:(NSInvocation *)invoc;
{
RxMapOperator *instance = [RxMapOperator new];
instance.stream = stream;
instance.invocUp = invoc;
return instance;
}
- (void)transform:(id)arg
{
[self.invocUp setArgument:&arg atIndex:2];
[self.invocUp invoke];
id ret;
[self.invocUp getReturnValue:&ret];
[self.invocDown setArgument:&ret atIndex:2];
[self.invocDown invoke];
}
- (void)subscribe:(NSInvocation *)invocation
{
self.invocDown = invocation;
[self.stream subscribe:[NSInvocation invocationWithTarget:self selector:@selector(transform:)]];
}
@end
@interface RxObservable : NSObject
+ (instancetype)observableFromArray:(NSArray *)array;
- (instancetype)mapWithInvocation:(NSInvocation *)invo;
- (void)subscribe:(NSInvocation *)invocation;
@end
#import "RxObservable.h"
#import "RxArraySource.h"
#import "RxMapOperator.h"
@implementation RxObservable
+ (instancetype)observableFromArray:(NSArray *)array;
{
return [RxArraySource createWithElements:array];
}
- (instancetype)mapWithInvocation:(NSInvocation *)invo
{
return [RxMapOperator operatorFromStream:self withInvocation:invo];
}
- (void)subscribe:(NSInvocation *)invocation;
{}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment