Skip to content

Instantly share code, notes, and snippets.

@lidio601
Last active July 31, 2019 23:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lidio601/983cfb4e3793322e1955eaab569ba715 to your computer and use it in GitHub Desktop.
Save lidio601/983cfb4e3793322e1955eaab569ba715 to your computer and use it in GitHub Desktop.
React Native - native module started kit (iOs)
// ...
#import "FooModule.h"
// ...
@interface AppDelegate ()
// ...
@property (nonatomic, strong) FooModule *fooModule;
// ...
@end
@implementation AppDelegate
// ...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ...
self.fooModule = [FooModule bootstrap];
// ...
}
// ...
@end
//
// FooModule.h
//
// Created by Fabio Cigliano on 1/08/19.
//
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
#define MODULE_NAME @"Foo"
#define EVENT_NAME @"change"
#define MLOG_FORMAT @"[foo] :: %s [Line %d] "
#define MLog(fmt, ...) NSLog((MLOG_FORMAT fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
NS_ASSUME_NONNULL_BEGIN
@interface FooModule : RCTEventEmitter <RCTBridgeModule>
+ (id) bootstrap;
@end
NS_ASSUME_NONNULL_END
//
// FooModule.m
//
// Created by Fabio Cigliano on 1/08/19.
//
#import "FooModule.h"
@interface FooModule (RCTEventEmitter)
@end
@interface FooModule ()
{
}
@property (nonatomic, assign) NSDate* lastUpdate;
@property (nonatomic, assign) BOOL isListening;
@property (nonatomic, assign) int listenerCount;
- (void)attachListener;
- (void)removeListener;
-(BOOL)hasListener;
@end
@implementation FooModule : RCTEventEmitter
#pragma mark - External
+ (id) bootstrap {
MLog(@"initialized");
return [[FooModule alloc] init];
}
#pragma mark - Internal
- (instancetype)init
{
self = [super init];
if (self) {
// init internal state
self.lastUpdate = nil;
self.isListening = NO;
self.listenerCount = 0;
// should we start any service at startup?
// [self attachListener];
}
return self;
}
- (void)dealloc
{
// remove any service
[self removeListener];
}
#pragma mark - State
// expose the internal state
- (NSDictionary*) getStateObject {
return @{
@"lastUpdate": @([self.lastUpdate timeIntervalSince1970])
};
}
#pragma mark - React
RCT_EXPORT_MODULE(ScreenStateModule);
+ (BOOL)requiresMainQueueSetup
{
return NO;
}
#pragma mark - Exported
RCT_EXPORT_METHOD(getState:(RCTResponseSenderBlock)callback)
{
callback(@[ [self getStateObject] ]);
}
#pragma mark - Event handling
- (NSArray<NSString *> *)supportedEvents
{
return @[ EVENT_NAME ];
}
// Will be called when this module's first listener is added.
-(void)startObserving {
// Set up any upstream listeners or background tasks as necessary
self.listenerCount++;
[self attachListener];
}
// Will be called when this module's last listener is removed, or on dealloc.
-(void)stopObserving {
// Remove upstream listeners, stop unnecessary background tasks
self.listenerCount--;
if (self.listenerCount <= 0) {
[self attachListener];
}
}
-(BOOL)hasListener {
return self.bridge != nil && self.listenerCount > 0;
}
#pragma mark - Services
- (void) attachListener
{
if (self.isListening) {
// skip this if already listening
return;
}
self.isListening = YES;
MLog(@"attachListener");
//
// TODO: add your service here
//
/*
for instance
// listen for lock state changes
notify_register_dispatch("com.apple.springboard.lockstate", &lockStateToken, dispatch_get_main_queue(), ^(int token) {
// here we forward events to js
[self readState];
});
*/
// at startup read and forward the state
[self readState];
}
- (void) removeListener
{
if (!self.isListening) {
// skip this if already stopped
return;
}
self.isListening = NO;
MLog(@"removeListener");
//
// TODO: add your service here
//
}
- (void) readState
{
BOOL didChange = NO;
//
// TODO: do something here
//
// trigger all the attached event listener
if ([self hasListener] && didChange) {
self.lastUpdate = [NSDate date];
NSDictionary* state = [self getStateObject];
MLog(@"new event %@", state);
[self sendEventWithName:EVENT_NAME body:state];
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment