Created
April 13, 2019 17:33
-
-
Save ericlewis/1c3912289e66d109b250231f1709953d to your computer and use it in GitHub Desktop.
react-native NativeModule for interacting with gmail objc google rest apis
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// RNGmailAPI.m | |
// astroboy | |
// | |
// Created by Eric Lewis on 4/9/19. | |
// Copyright © 2019 Eric Lewis. All rights reserved. | |
// | |
#import "RNGmailAPI.h" | |
#import "RNPromiseWrapper.h" | |
#import <GTLRGmail.h> | |
@interface RNGmailAPI () | |
@property (nonatomic) RNPromiseWrapper *promiseWrapper; | |
@property (nonatomic) GTLRGmailService *gmail; | |
@property (nonatomic) GTLRBatchQuery *batchQuery; | |
@property (nonatomic) GIDSignIn *signIn; | |
@end | |
@implementation RNGmailAPI | |
RCT_EXPORT_MODULE(); | |
- (instancetype)init | |
{ | |
self = [super init]; | |
if (self) { | |
self.promiseWrapper = [[RNPromiseWrapper alloc] init]; | |
self.gmail = [[GTLRGmailService alloc] init]; | |
self.signIn = [GIDSignIn sharedInstance]; | |
self.signIn.delegate = self; | |
} | |
return self; | |
} | |
- (NSDictionary *)constantsToExport | |
{ | |
return @{ @"initialIsLoggedIn": @(self.signIn.hasAuthInKeychain) }; | |
} | |
+ (BOOL)requiresMainQueueSetup | |
{ | |
return NO; | |
} | |
RCT_EXPORT_METHOD(initialize:(RCTPromiseResolveBlock)resolve | |
rejecter:(RCTPromiseRejectBlock)reject) | |
{ | |
if (self.signIn.currentUser == nil) { | |
NSString *methodName = @"initialize"; | |
[self.promiseWrapper setPromiseWithInProgressCheck:resolve rejecter:nil fromCallSite:methodName]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
[[GIDSignIn sharedInstance] signInSilently]; | |
}); | |
} else { | |
resolve(self.signIn.currentUser); | |
} | |
} | |
RCT_EXPORT_METHOD(executeQueries:(NSArray<NSDictionary *> *)queries | |
resolver:(RCTPromiseResolveBlock)resolve | |
rejecter:(RCTPromiseRejectBlock)reject) | |
{ | |
[self execute:[self createBatchQuery:queries] resolver:resolve rejecter:reject]; | |
} | |
- (void)execute:(GTLRBatchQuery *)query | |
resolver:(RCTPromiseResolveBlock)resolve | |
rejecter:(RCTPromiseRejectBlock)reject | |
{ | |
[self.gmail executeQuery:query | |
completionHandler:^(GTLRServiceTicket *ticket, GTLRBatchResult *batchResult, NSError *error) { | |
if (error == nil) { | |
// reset the global batcher (maybe there is a better way?) also, maybe we don't want to on error? | |
NSDictionary *successes = batchResult.successes; | |
NSMutableArray *successResponse = [[NSMutableArray alloc] initWithCapacity:successes.count]; | |
for (NSString *requestID in successes) { | |
GTLRObject *list = [successes objectForKey:requestID]; | |
[successResponse addObject:list.JSON]; | |
} | |
NSDictionary *failures = batchResult.failures; | |
NSMutableArray *failuresResponse = [[NSMutableArray alloc] initWithCapacity:failures.count]; | |
for (NSString *requestID in failures) { | |
GTLRErrorObject *errorObj = [failures objectForKey:requestID]; | |
[failuresResponse addObject:errorObj.JSON]; | |
} | |
resolve(@{ @"results": successResponse, @"errors": failuresResponse }); | |
} else { | |
reject(@"gmail_error", @"Something went wrong, yo.", error); | |
} | |
}]; | |
} | |
- (GTLRBatchQuery *)createBatchQuery:(NSArray<NSDictionary *> *)queries | |
{ | |
__block GTLRBatchQuery *batch = [GTLRBatchQuery batchQuery]; | |
[queries enumerateObjectsUsingBlock:^(NSDictionary *query, NSUInteger idx, BOOL * _Nonnull stop) { | |
[batch addQuery:[self createQueryFromDictionary:query]]; | |
}]; | |
return batch; | |
} | |
- (id)createQueryFromDictionary:(NSDictionary*)queryDict | |
{ | |
NSString *type = queryDict[@"type"]; | |
Class theClass = NSClassFromString([NSString stringWithFormat:@"GTLRGmailQuery_%@", type]); | |
id query = ( [type containsString:@"Trash"] | |
|| [type containsString:@"Untrash"] | |
|| [type containsString:@"Delete"] | |
|| [type containsString:@"Get"]) | |
? [theClass queryWithUserId:self.signIn.currentUser.userID identifier:queryDict[@"id"]] | |
: [theClass queryWithUserId:self.signIn.currentUser.userID]; | |
NSMutableDictionary *queryDictCopy = [queryDict mutableCopy]; | |
// clean off some things we don't wanna attach | |
[queryDictCopy removeObjectForKey:@"type"]; | |
[queryDictCopy removeObjectForKey:@"id"]; | |
[query setValuesForKeysWithDictionary:queryDictCopy]; | |
return query; | |
} | |
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user | |
withError:(NSError *)error | |
{ | |
if (error) { | |
[self.promiseWrapper reject:@"Error when revoking access." withError:error]; | |
return; | |
} | |
self.gmail.authorizer = [[user authentication] fetcherAuthorizer]; | |
[self.promiseWrapper resolve:(user)]; | |
} | |
- (void)signIn:(GIDSignIn *)signIn didDisconnectWithUser:(GIDGoogleUser *)user | |
withError:(NSError *)error | |
{ | |
if (error) { | |
[self.promiseWrapper reject:@"Error when disconnecting user." withError:error]; | |
return; | |
} | |
[self.promiseWrapper resolve:(user)]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment