From c41d30e455f4f9ce8b5717deb355055298693158 Mon Sep 17 00:00:00 2001 From: aaditya singh Date: Tue, 17 Sep 2024 10:37:39 +0530 Subject: [PATCH 1/2] build(iOS): migrated from objective C to Swift --- README.md | 2 +- example/src/App.js | 2 +- ios/SmallcaseGateway-Bridging-Header.h | 2 +- ios/SmallcaseGateway.m | 792 +++--------------- ios/SmallcaseGateway.swift | 570 +++++++++++++ .../project.pbxproj | 17 +- react-native-smallcase-gateway.podspec | 4 +- src/SmallcaseGateway.js | 6 +- types/index.d.ts | 2 +- 9 files changed, 679 insertions(+), 718 deletions(-) diff --git a/README.md b/README.md index 80a9d484..d46ef56e 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ await SmallcaseGateway.setConfigEnvironment({ }); // initialize session -await SmallcaseGateway.init(sdkToken); +await SmallcaseGateway.initSDK(sdkToken); // execute a transaction const res = await SmallcaseGateway.triggerTransaction(transactionId); diff --git a/example/src/App.js b/example/src/App.js index f8a386bc..520fea34 100644 --- a/example/src/App.js +++ b/example/src/App.js @@ -68,7 +68,7 @@ const App = () => { const init = useCallback(async () => { setLog((p) => p + '\n starting init'); try { - await SmallcaseGateway.init(sdkToken); + await SmallcaseGateway.initSDK(sdkToken); setLog((p) => p + '\n init success'); } catch (err: any) { setLog((p) => p + '\n error during init' + JSON.stringify(err.userInfo)); diff --git a/ios/SmallcaseGateway-Bridging-Header.h b/ios/SmallcaseGateway-Bridging-Header.h index dea7ff6b..755dfcf8 100644 --- a/ios/SmallcaseGateway-Bridging-Header.h +++ b/ios/SmallcaseGateway-Bridging-Header.h @@ -1,2 +1,2 @@ -#import #import +#import diff --git a/ios/SmallcaseGateway.m b/ios/SmallcaseGateway.m index 11627054..75a541a4 100644 --- a/ios/SmallcaseGateway.m +++ b/ios/SmallcaseGateway.m @@ -1,718 +1,116 @@ #import - #import #import - #import @interface RCT_EXTERN_MODULE(SmallcaseGateway, NSObject) -//MARK: SDK version helpers -RCT_REMAP_METHOD(setHybridSdkVersion, sdkVersion: (NSString *)sdkVersion) { - [SCGateway.shared setSDKTypeWithType:@"react-native"]; - [SCGateway.shared setHybridSDKVersionWithVersion:sdkVersion]; -} - -RCT_REMAP_METHOD(getSdkVersion, - reactNativeSdkVersion: (NSString *)reactNativeSdkVersion - initWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - - NSString *nativeSdkString = [NSString stringWithFormat: @"ios:%@", [SCGateway.shared getSdkVersion]]; - NSString *reactNativeSdkString = [NSString stringWithFormat: @",react-native:%@", reactNativeSdkVersion]; - - NSString *result = [nativeSdkString stringByAppendingString: reactNativeSdkString]; - - resolve(result); -} - -//MARK: SDK setup -RCT_REMAP_METHOD(setConfigEnvironment, - envName:(NSString *)envName - gateway:(NSString *)gateway - isLeprechaunActive: (BOOL *)isLeprechaunActive - isAmoEnabled: (BOOL *)isAmoEnabled - preProvidedBrokers: (NSArray *)preProvidedBrokers - setConfigEnvironmentWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - NSInteger environment = EnvironmentProduction; - - if([envName isEqualToString:@"production"]) { - environment = EnvironmentProduction; - } - else if([envName isEqualToString:@"development"]) { - environment = EnvironmentDevelopment; - } else { - environment = EnvironmentStaging; - } - - GatewayConfig *config = [[GatewayConfig alloc] - initWithGatewayName:gateway - brokerConfig:preProvidedBrokers - apiEnvironment:environment - isLeprechaunActive:isLeprechaunActive - isAmoEnabled:isAmoEnabled]; - - [SCGateway.shared setupWithConfig: config completion:^(BOOL success,NSError * error) { - if(success) { - resolve(@(YES)); - } else { - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - [responseDict setValue:[NSNumber numberWithInteger:error.code] forKey:@"errorCode"]; - [responseDict setValue:error.domain forKey:@"errorMessage"]; - - NSError *err = [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:responseDict]; - - reject(@"setConfigEnvironment", @"Env setup failed", err); - } - - }]; -} - -//MARK: SDK init -RCT_REMAP_METHOD(init, - sdkToken:(NSString *)sdkToken - initWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [SCGateway.shared initializeGatewayWithSdkToken:sdkToken completion:^(BOOL success, NSError * error) { - if(success) { - resolve(@(YES)); - } else { - if(error != nil) { - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - [responseDict setValue:[NSNumber numberWithInteger:error.code] forKey:@"errorCode"]; - [responseDict setValue:error.domain forKey:@"errorMessage"]; - - NSError *err = [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:responseDict]; - - reject(@"init", @"Error during init", err); - return; - } - reject(@"init", @"Error during init", error); - } - }]; -} - -//MARK: Trigger Mf Transaction -RCT_REMAP_METHOD(triggerMfTransaction, - transactionId:(NSString *)transactionId - triggerTransactionWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { -dispatch_async(dispatch_get_main_queue(), ^(void) { - [SCGateway.shared - triggerMfTransactionWithPresentingController: - [[[UIApplication sharedApplication] keyWindow] rootViewController] - transactionId: transactionId - completion: ^(id response, NSError * error) { - if (error != nil) { - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - [responseDict setValue:[NSNumber numberWithInteger:error.code] forKey:@"errorCode"]; - [responseDict setValue:error.domain forKey:@"errorMessage"]; - [responseDict setValue:[error.userInfo objectForKey: @"data"] forKey:@"data"]; - - NSError *err = [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:responseDict]; - - reject(@"triggerTransaction", @"Error during transaction", err); - return; - } - - //MARK: intent - mf transaction - if ([response isKindOfClass: [ObjCTransactionIntentMfHoldingsImport class]]) { - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - ObjCTransactionIntentMfHoldingsImport *trxResponse = response; - [responseDict setObject:@"TRANSACTION" forKey:@"transaction"]; - - NSData *decodedStringData = [[NSData alloc] initWithBase64EncodedString:trxResponse.data options: 0]; - NSString *decodedResponse = [[NSString alloc] initWithData:decodedStringData encoding:1]; - - [responseDict setObject:trxResponse.data forKey:@"data"]; - resolve(responseDict); - return; - } - - // no matching intent type - NSError *err = [[NSError alloc] initWithDomain:@"com.smallcase.gateway" code:0 userInfo:@{@"Error reason": @"no matching response type"}]; - reject(@"triggerMfTransaction", @"no matching response type", err); - }]; -}); - } - -//MARK: Trigger Transaction -RCT_REMAP_METHOD(triggerTransaction, - transactionId:(NSString *)transactionId - utmParams:(NSDictionary *)utmParams - brokerList:(NSArray *)brokerList - triggerTransactionWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - [SCGateway.shared - triggerTransactionFlowWithTransactionId:transactionId - presentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] - utmParams:utmParams - brokerConfig:brokerList - completion: ^(id response, NSError * error) { - if (error != nil) { - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - [responseDict setValue:[NSNumber numberWithInteger:error.code] forKey:@"errorCode"]; - [responseDict setValue:error.domain forKey:@"errorMessage"]; - [responseDict setValue:[error.userInfo objectForKey: @"data"] forKey:@"data"]; - - NSError *err = [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:responseDict]; - - reject(@"triggerTransaction", @"Error during transaction", err); - return; - } - - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - [responseDict setValue:[NSNumber numberWithBool:true] forKey:@"success"]; - - //MARK: intent - transaction - if ([response isKindOfClass: [ObjcTransactionIntentTransaction class]]) { - ObjcTransactionIntentTransaction *trxResponse = response; - [responseDict setObject:@"TRANSACTION" forKey:@"transaction"]; - - NSData *decodedStringData = [[NSData alloc] initWithBase64EncodedString:trxResponse.transaction options: 0]; - NSString *decodedResponse = [[NSString alloc] initWithData:decodedStringData encoding:1]; - - [responseDict setObject:decodedResponse forKey:@"data"]; - resolve(responseDict); - return; - } - - //MARK: intent - mfTransaction - if ([response isKindOfClass: [ObjcMfTransactionIntentTransaction class]]) { - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - ObjcMfTransactionIntentTransaction *trxResponse = response; - [responseDict setObject:@"TRANSACTION" forKey:@"transaction"]; - - [responseDict setObject:trxResponse.data forKey:@"data"]; - resolve(responseDict); - return; - } - - //MARK: intent - connect - if([response isKindOfClass: [ObjCTransactionIntentConnect class]]) { - ObjCTransactionIntentConnect *trxResponse = response; - [responseDict setValue:@"CONNECT" forKey:@"transaction"]; - - if (trxResponse.response != nil) { - [responseDict setValue:trxResponse.response forKey:@"data"]; - } - - resolve(responseDict); - return; - } - - //MARK: intent - connect - if([response isKindOfClass: [ObjCTransactionIntentOnboarding class]]) { - ObjCTransactionIntentOnboarding *trxResponse = response; - [responseDict setValue:@"ONBOARDING" forKey:@"transaction"]; +// SDK Version +RCT_EXTERN_METHOD(setHybridSdkVersion:(NSString *)sdkVersion) - if (trxResponse.response != nil) { - [responseDict setValue:trxResponse.response forKey:@"data"]; - } +RCT_EXTERN_METHOD(getSdkVersion:(NSString *)reactNativeSdkVersion + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) - resolve(responseDict); - return; - } +// SDK Setup +RCT_EXTERN_METHOD(setConfigEnvironment:(NSString *)envName + gateway:(NSString *)gateway + isLeprechaunActive:(nonnull NSNumber *)isLeprechaunActive + isAmoEnabled:(nonnull NSNumber *)isAmoEnabled + preProvidedBrokers:(NSArray *)preProvidedBrokers + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) - //MARK: intent - holdings import - if([response isKindOfClass: [ObjcTransactionIntentHoldingsImport class]]) { - ObjcTransactionIntentHoldingsImport *trxResponse = response; - [responseDict setValue:@"HOLDING_IMPORT" forKey:@"transaction"]; +// SDK Init +RCT_EXTERN_METHOD(initSDK:(NSString *)sdkToken + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) - NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; - [dict setValue: trxResponse.authToken forKey:@"smallcaseAuthToken"]; - [dict setValue: trxResponse.transactionId forKey:@"transactionId"]; - [dict setValue: trxResponse.broker forKey:@"broker"]; - [dict setValue: trxResponse.signup forKey:@"signup"]; - [responseDict setValue:dict forKey:@"data"]; - resolve(responseDict); - return; - } +// Trigger Mutual Fund Transaction +RCT_EXTERN_METHOD(triggerMfTransaction:(NSString *)transactionId + triggerTransactionWithResolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) - //MARK: intent - fetch funds - if([response isKindOfClass: [ObjcTransactionIntentFetchFunds class]]) { - ObjcTransactionIntentFetchFunds *trxResponse = response; - [responseDict setValue:@"FETCH_FUNDS" forKey:@"transaction"]; - - NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; - [dict setValue: trxResponse.authToken forKey:@"smallcaseAuthToken"]; - [dict setValue: trxResponse.transactionId forKey:@"transactionId"]; - [dict setValue: trxResponse.signup forKey:@"signup"]; - - [dict setValue:[NSNumber numberWithDouble:trxResponse.fund] forKey:@"fund"]; - - [responseDict setValue:dict forKey:@"data"]; - resolve(responseDict); - return; - } - - //MARK: intent - sip setup - if([response isKindOfClass: [ObjcTransactionIntentSipSetup class]]) { - ObjcTransactionIntentSipSetup *trxResponse = response; - [responseDict setValue:@"SIP_SETUP" forKey:@"transaction"]; - - NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; - [dict setValue: trxResponse.authToken forKey:@"smallcaseAuthToken"]; - [dict setValue: trxResponse.transactionId forKey:@"transactionId"]; - [dict setValue: trxResponse.sipAction forKey:@"sipAction"]; - [dict setValue: trxResponse.sipType forKey:@"sipType"]; - [dict setValue: trxResponse.frequency forKey:@"frequency"]; - [dict setValue: trxResponse.iscid forKey:@"iscid"]; - [dict setValue: trxResponse.scheduledDate forKey:@"scheduledDate"]; - [dict setValue: trxResponse.scid forKey:@"scid"]; - [dict setValue: trxResponse.sipActive ? @"YES" : @"NO" forKey:@"sipActive"]; - [dict setValue: [NSNumber numberWithDouble: trxResponse.sipAmount] forKey:@"sipAmount"]; - [dict setValue: trxResponse.signup forKey:@"signup"]; - - [responseDict setValue:dict forKey:@"data"]; - resolve(responseDict); - return; - } - - - //MARK: intent - authorize holdings - if([response isKindOfClass: [ObjcTransactionIntentAuthoriseHoldings class]]) { - ObjcTransactionIntentAuthoriseHoldings *trxResponse = response; - [responseDict setValue:@"AUTHORISE_HOLDINGS" forKey:@"transaction"]; - - NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; - [dict setValue: trxResponse.authToken forKey:@"smallcaseAuthToken"]; - [dict setValue: trxResponse.transactionId forKey:@"transactionId"]; - [dict setValue: trxResponse.signup forKey:@"signup"]; - - [dict setValue: [NSNumber numberWithBool:trxResponse.status] forKey:@"status"]; - - [responseDict setValue:dict forKey:@"data"]; - resolve(responseDict); - return; - } - - // no matching intent type - NSError *err = [[NSError alloc] initWithDomain:@"com.smallcase.gateway" code:0 userInfo:@{@"Error reason": @"no matching response type"}]; - reject(@"triggerTransaction", @"no matching response type", err); - }]; - }); -} - -//MARK: Show orders -RCT_REMAP_METHOD(showOrders, - showOrdersWithResolver: (RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - - [SCGateway.shared - showOrdersWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] - completion:^(BOOL success, NSError * error) { +// Trigger Transaction +RCT_EXTERN_METHOD(triggerTransaction:(NSString *)transactionId + utmParams:(NSDictionary *)utmParams + brokerList:(NSArray *)brokerList + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) - if(success){ - resolve(@(YES)); - } else { - [responseDict setValue:[NSNumber numberWithInteger:error.code] forKey:@"errorCode"]; - [responseDict setValue:error.domain forKey:@"error"]; - [responseDict setValue:[error.userInfo objectForKey: @"data"] forKey:@"data"]; - resolve(responseDict); - } - }]; - }); -} +// Show Orders +RCT_EXTERN_METHOD(showOrders:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) -//MARK: smallplug -RCT_REMAP_METHOD(launchSmallplug, - targetEndpoint:(NSString *)targetEndpoint +// Launch Smallplug +RCT_EXTERN_METHOD(launchSmallplug:(NSString *)targetEndpoint params:(NSString *)params - launchSmallplugWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - - SmallplugData *smallplugData = [[SmallplugData alloc] init:targetEndpoint :params]; - - [SCGateway.shared launchSmallPlugWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] smallplugData:smallplugData completion:^(id smallplugResponse, NSError * error) { - - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - - if (error != nil) { - NSLog(@"%@", error.domain); - double delayInSeconds = 0.5; - dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); - dispatch_after(popTime, dispatch_get_main_queue(), ^(void) { - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - [responseDict setValue:[NSNumber numberWithBool:false] forKey:@"success"]; - [responseDict setValue:[NSNumber numberWithInteger:error.code] forKey:@"errorCode"]; - [responseDict setValue:error.domain forKey:@"error"]; - - resolve(responseDict); - return; - }); - } else { - - if ([smallplugResponse isKindOfClass: [NSString class]]) { - NSLog(@"%@", smallplugResponse); - - [responseDict setValue:[NSNumber numberWithBool: true] forKey:@"success"]; - [responseDict setValue:smallplugResponse forKey:@"smallcaseAuthToken"]; - - double delayInSeconds = 0.5; - dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); - dispatch_after(popTime, dispatch_get_main_queue(), ^(void) { - - resolve(responseDict); - return; - - }); - } - } - - }]; - }); -} - -//MARK: smallplug with branding -RCT_REMAP_METHOD(launchSmallplugWithBranding, - targetEndpoint:(NSString *)targetEndpoint - params:(NSString *)params - headerColor:(NSString *)headerColor - headerOpacity:(nonnull NSNumber *)headerOpacity - backIconColor:(NSString *)backIconColor - backIconOpacity:(nonnull NSNumber *)backIconOpacity - launchSmallplugWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) -{ - dispatch_async(dispatch_get_main_queue(), ^(void) { - - SmallplugData *smallplugData = [[SmallplugData alloc] init:targetEndpoint :params]; - SmallplugUiConfig *smallplugUiConfig = [[SmallplugUiConfig alloc] initWithSmallplugHeaderColor:headerColor headerColorOpacity:headerOpacity backIconColor:backIconColor backIconColorOpacity:backIconOpacity]; - - [SCGateway.shared launchSmallPlugWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] smallplugData:smallplugData smallplugUiConfig:smallplugUiConfig completion:^(id smallplugResponse, NSError * error) { - - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - - if (error != nil) { - NSLog(@"%@", error.domain); - double delayInSeconds = 0.5; - dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); - dispatch_after(popTime, dispatch_get_main_queue(), ^(void) { - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - [responseDict setValue:[NSNumber numberWithBool:false] forKey:@"success"]; - [responseDict setValue:[NSNumber numberWithInteger:error.code] forKey:@"errorCode"]; - [responseDict setValue:error.domain forKey:@"error"]; - - resolve(responseDict); - return; - }); - } else { - - if ([smallplugResponse isKindOfClass: [NSString class]]) { - NSLog(@"%@", smallplugResponse); + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) - [responseDict setValue:[NSNumber numberWithBool: true] forKey:@"success"]; - [responseDict setValue:smallplugResponse forKey:@"smallcaseAuthToken"]; - - double delayInSeconds = 0.5; - dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); - dispatch_after(popTime, dispatch_get_main_queue(), ^(void) { - - resolve(responseDict); - return; - - }); - } - } - - }]; - }); -} - -//MARK: Archive smallcase -RCT_REMAP_METHOD(archiveSmallcase, - iscid:(NSString *)iscid - initWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [SCGateway.shared markSmallcaseArchiveWithIscid:iscid completion: ^(id response, NSError * error) { - if(error != nil) { - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - [responseDict setValue:[NSNumber numberWithInteger:error.code] forKey:@"errorCode"]; - [responseDict setValue:error.domain forKey:@"errorMessage"]; - - NSError *err = [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:responseDict]; - - reject(@"archiveSmallcase", @"Error during transaction", err); - return; - } - - NSString *archiveResponseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]; - - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - [responseDict setValue:[NSNumber numberWithBool:true] forKey:@"success"]; - - [responseDict setObject:archiveResponseString forKey:@"data"]; - resolve(responseDict); - return; - }]; -} - -//MARK: Lead Gen -RCT_REMAP_METHOD(triggerLeadGenWithStatus, - userParams: (NSDictionary *)userParams - leadGenGenWithResolver: (RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - - [SCGateway.shared triggerLeadGenWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] params:userParams - completion:^(NSString * leadGenResponse) { - resolve(leadGenResponse); - } - ]; - - }); -} - -RCT_EXPORT_METHOD(triggerLeadGen: (NSDictionary *)userParams utmParams:(NSDictionary *)utmParams) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - [SCGateway.shared triggerLeadGenWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] params:userParams utmParams: utmParams]; - }); -} - -RCT_REMAP_METHOD(triggerLeadGenWithLoginCta, - userParams: (NSDictionary *)userParams +// Launch Smallplug with Branding +RCT_EXTERN_METHOD(launchSmallplugWithBranding:(NSString *)targetEndpoint + params:(NSString *)params + headerColor:(NSString *)headerColor + headerOpacity:(nonnull NSNumber *)headerOpacity + backIconColor:(NSString *)backIconColor + backIconOpacity:(nonnull NSNumber *)backIconOpacity + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) + +// Archive Smallcase +RCT_EXTERN_METHOD(archiveSmallcase:(NSString *)iscid + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) + +// Trigger Lead Generation +RCT_EXTERN_METHOD(triggerLeadGenWithStatus:(NSDictionary *)userParams + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) + +RCT_EXTERN_METHOD(triggerLeadGen:(NSDictionary *)userParams + utmParams:(NSDictionary *)utmParams) + +RCT_EXTERN_METHOD(triggerLeadGenWithLoginCta:(NSDictionary *)userParams utmParams:(NSDictionary *)utmParams - showLoginCta:(BOOL *)showLoginCta - leadGenGenWithResolver: (RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject - ) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - [SCGateway.shared - triggerLeadGenWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] params:userParams utmParams:utmParams retargeting:false showLoginCta:showLoginCta completion:^(NSString * leadGenResponse) { - resolve(leadGenResponse); - }]; - }); -} - -//MARK: User logout -RCT_REMAP_METHOD(logoutUser, - logoutUserWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - [SCGateway.shared - logoutUserWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] - completion:^(BOOL success, NSError * error) { - if(success){ - resolve(@(YES)); - } else { - reject(@"logout", @"Error during logout", error); - } - }]; - }); -} - -//MARK: Loans - -RCT_REMAP_METHOD(setupLoans, - loanConfig: (NSDictionary *)loanConfig - setupLoansWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject - ) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - - if(loanConfig != nil && loanConfig[@"gatewayName"] != nil) { - - NSString *gatewayName = loanConfig[@"gatewayName"]; - NSLog(@" ----------- Gateway Name: %@", gatewayName); - - NSString *envName = [NSString stringWithFormat:@"%@", loanConfig[@"environment"]]; - NSLog(@" ----------- Env Name: %@", envName); - - NSNumber *lasEnv = @0; - - if([envName isEqualToString:@"production"]) { - lasEnv = @0; - } - else if([envName isEqualToString:@"development"]) { - lasEnv = @1; - } else { - lasEnv = @2; - } - - ScLoanConfig *gatewayLoanConfig = [[ScLoanConfig alloc] initWithGatewayName:gatewayName environment:lasEnv]; - - [ScLoan.instance setupWithConfig:gatewayLoanConfig completion:^(ScLoanSuccess * success, ScLoanError * error) { - - if(error != nil) { - reject([NSString stringWithFormat:@"%li", (long)error.errorCode], error.errorMessage, [self scLoanErrorToDict:error]); - return; - } - resolve([self scLoanSuccessToDict:success]); - }]; - } - - }); -} - -RCT_REMAP_METHOD(apply, - loanInfo: (NSDictionary *)loanInfo - applyWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject - ) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - - if(loanInfo != nil && loanInfo[@"interactionToken"] != nil) { - - NSString *interactionToken = loanInfo[@"interactionToken"]; - NSLog(@" ----------- Interaction Token: %@", interactionToken); - - ScLoanInfo *gatewayLoanInfo = [[ScLoanInfo alloc] initWithInteractionToken:interactionToken]; - - [ScLoan.instance applyWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] loanInfo:gatewayLoanInfo completion:^(ScLoanSuccess * success, ScLoanError * error) { - - if(error != nil) { - reject([NSString stringWithFormat:@"%li", (long)error.errorCode], error.errorMessage, [self scLoanErrorToDict:error]); - return; - } - resolve([self scLoanSuccessToDict:success]); - }]; - } - - }); -} - -RCT_REMAP_METHOD(pay, - loanInfo: (NSDictionary *)loanInfo - payWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject - ) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - - if(loanInfo != nil && loanInfo[@"interactionToken"] != nil) { - - NSString *interactionToken = loanInfo[@"interactionToken"]; - NSLog(@" ----------- Interaction Token: %@", interactionToken); - - ScLoanInfo *gatewayLoanInfo = [[ScLoanInfo alloc] initWithInteractionToken:interactionToken]; - - [ScLoan.instance payWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] loanInfo:gatewayLoanInfo completion:^(ScLoanSuccess * success, ScLoanError * error) { - - if(error != nil) { - reject([NSString stringWithFormat:@"%li", (long)error.errorCode], error.errorMessage, [self scLoanErrorToDict:error]); - return; - } - resolve([self scLoanSuccessToDict:success]); - }]; - } - - }); -} - -RCT_REMAP_METHOD(withdraw, - loanInfo: (NSDictionary *)loanInfo - withdrawWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject - ) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - - if(loanInfo != nil && loanInfo[@"interactionToken"] != nil) { - - NSString *interactionToken = loanInfo[@"interactionToken"]; - NSLog(@" ----------- Interaction Token: %@", interactionToken); - - ScLoanInfo *gatewayLoanInfo = [[ScLoanInfo alloc] initWithInteractionToken:interactionToken]; - - [ScLoan.instance withdrawWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] loanInfo:gatewayLoanInfo completion:^(ScLoanSuccess * success, ScLoanError * error) { - - if(error != nil) { - reject([NSString stringWithFormat:@"%li", (long)error.errorCode], error.errorMessage, [self scLoanErrorToDict:error]); - return; - } - resolve([self scLoanSuccessToDict:success]); - }]; - } - - }); -} - -RCT_REMAP_METHOD(service, - loanInfo: (NSDictionary *)loanInfo - serviceWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject - ) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - - if(loanInfo != nil && loanInfo[@"interactionToken"] != nil) { - - NSString *interactionToken = loanInfo[@"interactionToken"]; - NSLog(@" ----------- Interaction Token: %@", interactionToken); - - ScLoanInfo *gatewayLoanInfo = [[ScLoanInfo alloc] initWithInteractionToken:interactionToken]; - - [ScLoan.instance serviceWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] loanInfo:gatewayLoanInfo completion:^(ScLoanSuccess * success, ScLoanError * error) { - - if(error != nil) { - reject([NSString stringWithFormat:@"%li", (long)error.errorCode], error.errorMessage, [self scLoanErrorToDict:error]); - return; - } - resolve([self scLoanSuccessToDict:success]); - - }]; - } - - }); -} - -RCT_REMAP_METHOD(triggerInteraction, - loanInfo: (NSDictionary *)loanInfo - triggerInteractionWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject - ) { - dispatch_async(dispatch_get_main_queue(), ^(void) { - - if(loanInfo != nil && loanInfo[@"interactionToken"] != nil) { - - NSString *interactionToken = loanInfo[@"interactionToken"]; - NSLog(@" ----------- Interaction Token: %@", interactionToken); - - ScLoanInfo *gatewayLoanInfo = [[ScLoanInfo alloc] initWithInteractionToken:interactionToken]; - - [ScLoan.instance triggerInteractionWithPresentingController:[[[UIApplication sharedApplication] keyWindow] rootViewController] loanInfo:gatewayLoanInfo completion:^(ScLoanSuccess * success, ScLoanError * error) { - - if(error != nil) { - reject([NSString stringWithFormat:@"%li", (long)error.errorCode], error.errorMessage, [self scLoanErrorToDict:error]); - return; - } - resolve([self scLoanSuccessToDict:success]); - - }]; - } - - }); -} - -- (NSDictionary *)scLoanSuccessToDict:(ScLoanSuccess *)success { - NSMutableDictionary *successDict = [NSMutableDictionary dictionary]; - successDict[@"isSuccess"] = @(success.isSuccess); - - id data = success.data; - if (data && ![data isKindOfClass:[NSNull class]]) { - successDict[@"data"] = data; - } - - return successDict; -} - -- (NSError *)scLoanErrorToDict:(ScLoanError *)error { - - NSMutableDictionary *responseDict = [[NSMutableDictionary alloc] init]; - [responseDict setValue:[NSNumber numberWithInteger:error.errorCode] forKey:@"code"]; - [responseDict setValue:error.errorMessage forKey:@"message"]; - [responseDict setValue:error.data forKey:@"data"]; - [responseDict setValue:@NO forKey:@"isSuccess"]; - - NSError *err = [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:responseDict]; - return err; - -} + showLoginCta:(BOOL)showLoginCta + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) + +// User Logout +RCT_EXTERN_METHOD(logoutUser:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) + +// Loans Setup +RCT_EXTERN_METHOD(setupLoans:(NSDictionary *)loanConfig + withResolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) + +// Apply for Loan +RCT_EXTERN_METHOD(apply:(NSDictionary *)loanInfo + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) + +// Pay Loan +RCT_EXTERN_METHOD(pay:(NSDictionary *)loanInfo + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) + +// Withdraw Loan +RCT_EXTERN_METHOD(withdraw:(NSDictionary *)loanInfo + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) + +// Service Loan +RCT_EXTERN_METHOD(service:(NSDictionary *)loanInfo + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) + +// Trigger Interaction +RCT_EXTERN_METHOD(triggerInteraction:(NSDictionary *)loanInfo + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) @end diff --git a/ios/SmallcaseGateway.swift b/ios/SmallcaseGateway.swift index 6be428fc..75a33ecd 100644 --- a/ios/SmallcaseGateway.swift +++ b/ios/SmallcaseGateway.swift @@ -1,3 +1,573 @@ + +import React +import SCGateway +import Loans + @objc(SmallcaseGateway) class SmallcaseGateway: NSObject { + + // MARK: SDK version helpers + @objc(setHybridSdkVersion:) + func setHybridSdkVersion(_ sdkVersion: String) { + SCGateway.shared.setSDKType(type: "react-native") + SCGateway.shared.setHybridSDKVersion(version: sdkVersion) + } + + @objc(getSdkVersion:resolver:rejecter:) + func getSdkVersion(reactNativeSdkVersion: String, + withResolver resolve: @escaping RCTPromiseResolveBlock, + rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + let nativeSdkString = "ios:\(SCGateway.shared.getSdkVersion())" + let reactNativeSdkString = ",react-native:\(reactNativeSdkVersion)" + let result = nativeSdkString + reactNativeSdkString + + resolve(result) + } + } + + + // MARK: SDK setup + @objc(setConfigEnvironment:gateway:isLeprechaunActive:isAmoEnabled:preProvidedBrokers:resolver:rejecter:) + func setConfigEnvironment(envName: String, + gateway: String, + isLeprechaunActive: NSNumber, + isAmoEnabled: NSNumber, + preProvidedBrokers: [Any], + resolver resolve: @escaping RCTPromiseResolveBlock, + rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + let environment: Int + switch envName { + case "production": + environment = Environment.production.rawValue + case "development": + environment = Environment.development.rawValue + default: + environment = Environment.staging.rawValue + } + + guard let brokerList = preProvidedBrokers as? [String] else { + let error = NSError(domain: "preProvidedBrokers is not of type [String]", code: -1, userInfo: nil) + reject("brokerList_error", "Broker list is not of the expected type [String]", error) + return + } + + let config = GatewayConfig(gatewayName: gateway, + brokerConfig: brokerList, + apiEnvironment: Environment(rawValue: environment)!, + isLeprechaunActive: isLeprechaunActive.boolValue, + isAmoEnabled: isAmoEnabled.boolValue) + + SCGateway.shared.setup(config: config) { success, error in + if success { + resolve(true) + } else { + var responseDict = [String: Any]() + if let error = error as NSError? { + responseDict["errorCode"] = error.code + responseDict["errorMessage"] = error.domain + let err = NSError(domain: error.domain, code: error.code, userInfo: responseDict) + reject("setConfigEnvironment", "Env setup failed", err) + } + } + } + } + } + + + // MARK: SDK init + @objc(initSDK:resolver:rejecter:) + func initSDK(sdkToken: String, + withResolver resolve: @escaping RCTPromiseResolveBlock, + rejecter reject: @escaping RCTPromiseRejectBlock) { + SCGateway.shared.initializeGateway(sdkToken) { success, error in + if !success.isEmpty { + resolve(true) + } else { + if let error = error as? NSError { + let responseDict: [String: Any] = [ + "errorCode": error.code, + "errorMessage": error.domain + ] + let err = NSError(domain: error.domain, code: error.code, userInfo: responseDict) + reject("initSDK", "Error during initSDK", err) + } else { + reject("initSDK", "Error during initSDK", error) + } + } + } + } + + + + +// MARK: Trigger Mf Transaction + @objc(triggerMfTransaction:resolver:rejecter:) + func triggerMfTransaction(transactionId: String, + triggerTransactionWithResolver resolve: @escaping RCTPromiseResolveBlock, + rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + SCGateway.shared.triggerMfTransaction(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, + transactionId: transactionId) { response, error in + if let error = error { + let responseDict: [String: Any] = [ + "errorCode": error.code, + "errorMessage": error.domain, + "data": error.userInfo["data"] ?? NSNull() + ] + let err = NSError(domain: error.domain, code: error.code, userInfo: responseDict) + reject("triggerMfTransaction", "Error during transaction", err) + } else { + var responseDict: [String: Any] = [:] + if let trxResponse = response as? _ObjCTransactionIntentMfHoldingsImport { + responseDict["transaction"] = "TRANSACTION" + if let decodedStringData = Data(base64Encoded: trxResponse.data!) { + let decodedResponse = String(data: decodedStringData, encoding: .utf8) ?? "" + responseDict["data"] = trxResponse.data + resolve(responseDict) + } else { + reject("triggerMfTransaction", "Error decoding data", NSError(domain: "com.smallcase.gateway", code: 0, userInfo: ["Error reason": "data decoding error"])) + } + } else { + let err = NSError(domain: "com.smallcase.gateway", code: 0, userInfo: ["Error reason": "no matching response type"]) + reject("triggerMfTransaction", "no matching response type", err) + } + } + } + } + } + + + +// MARK: Trigger Transaction +@objc(triggerTransaction:utmParams:brokerList:resolver:rejecter:) +func triggerTransaction(transactionId: String, + utmParams: [String: Any], + brokerList: [[String: Any]], + triggerTransactionWithResolver resolve: @escaping RCTPromiseResolveBlock, + rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + + guard let utmParams = utmParams as? [String: String] else { + reject("error", "Invalid UTM parameters", nil) + return + } + let brokerConfig = brokerList.compactMap { $0["brokerName"] as? String } + + SCGateway.shared.triggerTransactionFlow(transactionId: transactionId, + presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, + utmParams: utmParams, + brokerConfig: brokerConfig) { response, error in + if let error = error { + let responseDict: [String: Any] = [ + "errorCode": error.code, + "errorMessage": error.domain, + "data": error.userInfo["data"] ?? NSNull() + ] + let err = NSError(domain: error.domain, code: error.code, userInfo: responseDict) + reject("triggerTransaction", "Error during transaction", err) + } else { + var responseDict: [String: Any] = ["success": true] + if let trxResponse = response as? _ObjcTransactionIntentTransaction { + responseDict["transaction"] = "TRANSACTION" + if let decodedStringData = Data(base64Encoded: trxResponse.transaction!) { + let decodedResponse = String(data: decodedStringData, encoding: .utf8) ?? "" + responseDict["data"] = decodedResponse + resolve(responseDict) + } else { + reject("triggerTransaction", "Error decoding data", NSError(domain: "com.smallcase.gateway", code: 0, userInfo: ["Error reason": "data decoding error"])) + } + } else if let trxResponse = response as? _ObjcMfTransactionIntentTransaction { + responseDict["transaction"] = "TRANSACTION" + responseDict["data"] = trxResponse.data + resolve(responseDict) + } else if let trxResponse = response as? _ObjCTransactionIntentConnect { + responseDict["transaction"] = "CONNECT" + responseDict["data"] = trxResponse.response ?? NSNull() + resolve(responseDict) + } else if let trxResponse = response as? _ObjCTransactionIntentOnboarding { + responseDict["transaction"] = "ONBOARDING" + responseDict["data"] = trxResponse.response ?? NSNull() + resolve(responseDict) + } else if let trxResponse = response as? _ObjcTransactionIntentHoldingsImport { + responseDict["transaction"] = "HOLDING_IMPORT" + let dict: [String: Any] = [ + "smallcaseAuthToken": trxResponse.authToken, + "transactionId": trxResponse.transactionId, + "broker": trxResponse.broker, + "signup": trxResponse.signup + ] + responseDict["data"] = dict + resolve(responseDict) + } else if let trxResponse = response as? _ObjcTransactionIntentFetchFunds { + responseDict["transaction"] = "FETCH_FUNDS" + let dict: [String: Any] = [ + "smallcaseAuthToken": trxResponse.authToken, + "transactionId": trxResponse.transactionId, + "signup": trxResponse.signup, + "fund": trxResponse.fund + ] + responseDict["data"] = dict + resolve(responseDict) + } else if let trxResponse = response as? _ObjcTransactionIntentSipSetup { + responseDict["transaction"] = "SIP_SETUP" + let dict: [String: Any] = [ + "smallcaseAuthToken": trxResponse.authToken, + "transactionId": trxResponse.transactionId, + "sipAction": trxResponse.sipAction, + "sipType": trxResponse.sipType, + "frequency": trxResponse.frequency, + "iscid": trxResponse.iscid, + "scheduledDate": trxResponse.scheduledDate, + "scid": trxResponse.scid, + "sipActive": trxResponse.sipActive ? "YES" : "NO", + "sipAmount": trxResponse.sipAmount, + "signup": trxResponse.signup + ] + responseDict["data"] = dict + resolve(responseDict) + } else if let trxResponse = response as? _ObjcTransactionIntentAuthoriseHoldings { + responseDict["transaction"] = "AUTHORISE_HOLDINGS" + let dict: [String: Any] = [ + "smallcaseAuthToken": trxResponse.authToken, + "transactionId": trxResponse.transactionId, + "signup": trxResponse.signup, + "status": trxResponse.status + ] + responseDict["data"] = dict + resolve(responseDict) + } else { + let err = NSError(domain: "com.smallcase.gateway", code: 0, userInfo: ["Error reason": "no matching response type"]) + reject("triggerTransaction", "no matching response type", err) + } + } + } + } } + + + // MARK: Show orders + @objc(showOrders:rejecter:) + func showOrders(withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + SCGateway.shared.showOrders(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!) { success, error in + if success { + resolve(true) + } else { + var responseDict = [String: Any]() + if let error = error as? NSError { + responseDict["errorCode"] = error.code + responseDict["error"] = error.domain + responseDict["data"] = error.userInfo["data"] + } + resolve(responseDict) + } + } + } + } + + // MARK: Smallplug + @objc(launchSmallplug:params:resolver:rejecter:) + func launchSmallplug(targetEndpoint: String, params: String, withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + let smallplugData = SmallplugData(targetEndpoint, params) + + SCGateway.shared.launchSmallPlug(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, smallplugData: smallplugData) { smallplugResponse, error in + var responseDict = [String: Any]() + + if let error = error as? NSError { + print(error.domain) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + responseDict["success"] = false + responseDict["errorCode"] = error.code + responseDict["error"] = error.domain + resolve(responseDict) + } + return + } + + if let smallplugResponse = smallplugResponse as? String { + print(smallplugResponse) + responseDict["success"] = true + responseDict["smallcaseAuthToken"] = smallplugResponse + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + resolve(responseDict) + } + } + } + } +} + + // MARK: Smallplug with branding + @objc(launchSmallplugWithBranding:params:headerColor:headerOpacity:backIconColor:backIconOpacity:resolver:rejecter:) + func launchSmallplugWithBranding(targetEndpoint: String, params: String, headerColor: String, headerOpacity: NSNumber, backIconColor: String, backIconOpacity: NSNumber, withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + let smallplugData = SmallplugData(targetEndpoint, params) + let smallplugUiConfig = SmallplugUiConfig(smallplugHeaderColor: headerColor, headerColorOpacity: headerOpacity, backIconColor: backIconColor, backIconColorOpacity: backIconOpacity) + + SCGateway.shared.launchSmallPlug(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, smallplugData: smallplugData, smallplugUiConfig: smallplugUiConfig) { smallplugResponse, error in + var responseDict = [String: Any]() + + if let error = error as? NSError { + print(error.domain) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + responseDict["success"] = false + responseDict["errorCode"] = error.code + responseDict["error"] = error.domain + resolve(responseDict) + } + return + } + + if let smallplugResponse = smallplugResponse as? String { + print(smallplugResponse) + responseDict["success"] = true + responseDict["smallcaseAuthToken"] = smallplugResponse + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + resolve(responseDict) + } + } + } + } + } + + // MARK: Archive smallcase + @objc(archiveSmallcase:resolver:rejecter:) + func archiveSmallcase(iscid: String, withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + SCGateway.shared.markSmallcaseArchive(iscid: iscid) { response, error in + if let error = error as NSError? { + var responseDict = [String: Any]() + responseDict["errorCode"] = error.code + responseDict["errorMessage"] = error.domain + let err = NSError(domain: error.domain, code: error.code, userInfo: responseDict) + reject("archiveSmallcase", "Error during transaction", err) + return + } + + let archiveResponseString = String(data: response!, encoding: .utf8) ?? "" + var responseDict = [String: Any]() + responseDict["success"] = true + responseDict["data"] = archiveResponseString + resolve(responseDict) + } + } + + + // MARK: Lead Gen + @objc(triggerLeadGenWithStatus:resolver:rejecter:) + func triggerLeadGenWithStatus(userParams: [String: Any], withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + guard let userParams = userParams as? [String: String] else { + reject("error", "Invalid UTM parameters", nil) + return + } + SCGateway.shared.triggerLeadGen(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, params: userParams) { leadGenResponse in + resolve(leadGenResponse) + } + } + } + + @objc(triggerLeadGen:utmParams:) + func triggerLeadGen(userParams: [String: Any], utmParams: [String: Any]) { + DispatchQueue.main.async { + + guard let utmParams = utmParams as? [String: String], + let userParams = userParams as? [String: String] + else { + return + } + SCGateway.shared.triggerLeadGen(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, params: userParams, utmParams: utmParams) + } + } + + @objc(triggerLeadGenWithLoginCta:userParams:utmParams:resolver:rejecter:) + func triggerLeadGenWithLoginCta(userParams: [String: Any], utmParams: [String: Any], showLoginCta: Bool, withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + guard let utmParams = utmParams as? [String: String], + let userParams = userParams as? [String: String] + else { + reject("error", "Invalid UTM parameters", nil) + return + } + + SCGateway.shared.triggerLeadGen(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, params: userParams, utmParams: utmParams, retargeting: false, showLoginCta: showLoginCta) { leadGenResponse in + resolve(leadGenResponse) + } + } + } + + + // MARK: User logout + @objc(logoutUser:rejecter:) + func logoutUser(withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + SCGateway.shared.logoutUser(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!) { success, error in + if success { + resolve(true) + } else { + reject("logout", "Error during logout", error) + } + } + } + } + + // MARK: Loans + @objc(setupLoans:withResolver:rejecter:) + func setupLoans(_ loanConfig: [String: Any], + withResolver resolve: @escaping RCTPromiseResolveBlock, + rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + if let gatewayName = loanConfig["gatewayName"] as? String { + print(" ----------- Gateway Name: \(gatewayName)") + + let envName = loanConfig["environment"] as? String ?? "" + print(" ----------- Env Name: \(envName)") + + let lasEnv: NSNumber + switch envName { + case "production": + lasEnv = 0 + case "development": + lasEnv = 1 + default: + lasEnv = 2 + } + + let gatewayLoanConfig = ScLoanConfig(gatewayName: gatewayName, environment: lasEnv) + + ScLoan.instance.setup(config: gatewayLoanConfig) { success, error in + if let error = error { + reject("\(error.errorCode)", error.errorMessage, self.scLoanErrorToDict(error)) + } else { + resolve(self.scLoanSuccessToDict(success!)) + } + } + } + } + } + + + @objc(apply:resolver:rejecter:) + func apply(loanInfo: [String: Any], withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + if let interactionToken = loanInfo["interactionToken"] as? String { + print(" ----------- Interaction Token: \(interactionToken)") + + let gatewayLoanInfo = ScLoanInfo(interactionToken: interactionToken) + + ScLoan.instance.apply(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, loanInfo: gatewayLoanInfo) { success, error in + if let error = error { + reject("\(error.errorCode)", error.errorMessage, self.scLoanErrorToDict(error)) + } else { + resolve(self.scLoanSuccessToDict(success!)) + } + } + } + } + } + + + @objc(pay:resolver:rejecter:) + func pay(loanInfo: [String: Any], withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + if let interactionToken = loanInfo["interactionToken"] as? String { + print(" ----------- Interaction Token: \(interactionToken)") + + let gatewayLoanInfo = ScLoanInfo(interactionToken: interactionToken) + + ScLoan.instance.pay(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, loanInfo: gatewayLoanInfo) { success, error in + if let error = error { + reject("\(error.errorCode)", error.errorMessage, self.scLoanErrorToDict(error)) + } else { + resolve(self.scLoanSuccessToDict(success!)) + } + } + } + } + } + + + @objc(withdraw:resolver:rejecter:) + func withdraw(loanInfo: [String: Any], withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + if let interactionToken = loanInfo["interactionToken"] as? String { + print(" ----------- Interaction Token: \(interactionToken)") + + let gatewayLoanInfo = ScLoanInfo(interactionToken: interactionToken) + + ScLoan.instance.withdraw(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, loanInfo: gatewayLoanInfo) { success, error in + if let error = error { + reject("\(error.errorCode)", error.errorMessage, self.scLoanErrorToDict(error)) + } else { + resolve(self.scLoanSuccessToDict(success!)) + } + } + } + } + } + + + @objc(service:resolver:rejecter:) + func service(loanInfo: [String: Any], withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + if let interactionToken = loanInfo["interactionToken"] as? String { + print(" ----------- Interaction Token: \(interactionToken)") + + let gatewayLoanInfo = ScLoanInfo(interactionToken: interactionToken) + + ScLoan.instance.service(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, loanInfo: gatewayLoanInfo) { success, error in + if let error = error { + reject("\(error.errorCode)", error.errorMessage, self.scLoanErrorToDict(error)) + } else { + resolve(self.scLoanSuccessToDict(success!)) + } + } + } + } + } + + + @objc(triggerInteraction:resolver:rejecter:) + func triggerInteraction(loanInfo: [String: Any], withResolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + if let interactionToken = loanInfo["interactionToken"] as? String { + print(" ----------- Interaction Token: \(interactionToken)") + + let gatewayLoanInfo = ScLoanInfo(interactionToken: interactionToken) + + ScLoan.instance.triggerInteraction(presentingController: (UIApplication.shared.keyWindow?.rootViewController)!, loanInfo: gatewayLoanInfo) { success, error in + if let error = error { + reject("\(error.errorCode)", error.errorMessage, self.scLoanErrorToDict(error)) + } else { + resolve(self.scLoanSuccessToDict(success!)) + } + } + } + } + } + + + // Helper methods + private func scLoanSuccessToDict(_ success: ScLoanSuccess) -> [String: Any] { + var successDict: [String: Any] = ["isSuccess": success.isSuccess] + if let data = success.data { + successDict["data"] = data + } + return successDict + } + + private func scLoanErrorToDict(_ error: ScLoanError) -> NSError { + let responseDict: [String: Any] = [ + "code": error.errorCode, + "message": error.errorMessage, + "data": error.data ?? NSNull(), + "isSuccess": false + ] + return NSError(domain: error.domain, code: error.code, userInfo: responseDict) + } + + + +} + diff --git a/ios/SmallcaseGateway.xcodeproj/project.pbxproj b/ios/SmallcaseGateway.xcodeproj/project.pbxproj index ac4ebb6a..534368cc 100644 --- a/ios/SmallcaseGateway.xcodeproj/project.pbxproj +++ b/ios/SmallcaseGateway.xcodeproj/project.pbxproj @@ -7,8 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 5E555C0D2413F4C50049A1A2 /* SmallcaseGateway.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* SmallcaseGateway.m */; }; - F4FF95D7245B92E800C19C63 /* SmallcaseGateway.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF95D6245B92E800C19C63 /* SmallcaseGateway.swift */; }; + F4FF95D7245B92E800C19C63 /* SmallcaseGateway.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF95D6245B92E800C19C63 /* SmallcaseGateway.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -49,13 +48,6 @@ name = Products; sourceTree = ""; }; - 158F56C62901D6B600238D90 /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; 58B511D21A9E6C8500147676 = { isa = PBXGroup; children = ( @@ -124,7 +116,6 @@ buildActionMask = 2147483647; files = ( F4FF95D7245B92E800C19C63 /* SmallcaseGateway.swift in Sources */, - B3E7B58A1CC2AC0600A0062D /* SmallcaseGateway.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -229,13 +220,14 @@ 58B511F01A9E6C8500147676 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../../../React/**", "$(SRCROOT)/../../react-native/React/**", ); - LIBRARY_SEARCH_PATHS = "$(inherited)"; + LIBRARY_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = SmallcaseGateway; SKIP_INSTALL = YES; @@ -248,13 +240,14 @@ 58B511F11A9E6C8500147676 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../../../React/**", "$(SRCROOT)/../../react-native/React/**", ); - LIBRARY_SEARCH_PATHS = "$(inherited)"; + LIBRARY_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = SmallcaseGateway; SKIP_INSTALL = YES; diff --git a/react-native-smallcase-gateway.podspec b/react-native-smallcase-gateway.podspec index 08e63188..714fb103 100644 --- a/react-native-smallcase-gateway.podspec +++ b/react-native-smallcase-gateway.podspec @@ -33,6 +33,6 @@ Pod::Spec.new do |s| s.dependency "ReactCommon/turbomodule/core" end - s.dependency 'SCGateway', '4.0.1' - s.dependency 'SCLoans', '3.1.0' + s.dependency 'SCGateway', '4.0.2' + s.dependency 'SCLoans', '3.1.1' end diff --git a/src/SmallcaseGateway.js b/src/SmallcaseGateway.js index 2500c071..ec825891 100644 --- a/src/SmallcaseGateway.js +++ b/src/SmallcaseGateway.js @@ -76,9 +76,9 @@ const setConfigEnvironment = async (envConfig) => { * note: this must be called after `setConfigEnvironment()` * @param {string} sdkToken */ -const init = async (sdkToken) => { +const initSDK = async (sdkToken) => { const safeToken = typeof sdkToken === 'string' ? sdkToken : ''; - return SmallcaseGatewayNative.init(safeToken); + return SmallcaseGatewayNative.initSDK(safeToken); }; /** @@ -278,7 +278,7 @@ const getSdkVersion = async () => { }; const SmallcaseGateway = { - init, + initSDK, logoutUser, triggerLeadGen, triggerLeadGenWithStatus, diff --git a/types/index.d.ts b/types/index.d.ts index fbeea1f7..67bd41c3 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -33,7 +33,7 @@ declare const _default: { authorizeHoldings: string; mfHoldingsImport: string; }; - init: (sdkToken: string) => unknown; + initSDK: (sdkToken: string) => unknown; logoutUser: () => Promise; triggerLeadGen: (userDetails?: import("./SmallcaseGateway").userDetails, utmParams?: any) => any; triggerLeadGenWithStatus: (userDetails?: import("./SmallcaseGateway").userDetails) => Promise; From 2ffb934237badc68aab214251d0afbd2ae1cf788 Mon Sep 17 00:00:00 2001 From: aaditya singh Date: Fri, 15 Nov 2024 22:27:15 +0530 Subject: [PATCH 2/2] build: scg and loans updated on iOS and Android --- android/build.gradle | 2 +- react-native-smallcase-gateway.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 3ead979f..28f3185f 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -149,7 +149,7 @@ def kotlin_version = getExtOrDefault('kotlinVersion') dependencies { //noinspection GradleDynamicVersion implementation 'com.facebook.react:react-native:+' // From node_modules - implementation 'com.smallcase.gateway:sdk:4.1.0' + implementation 'com.smallcase.gateway:sdk:4.2.1' implementation 'com.smallcase.loans:sdk:3.1.0' implementation "androidx.core:core-ktx:1.3.1" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" diff --git a/react-native-smallcase-gateway.podspec b/react-native-smallcase-gateway.podspec index 714fb103..77f495e8 100644 --- a/react-native-smallcase-gateway.podspec +++ b/react-native-smallcase-gateway.podspec @@ -33,6 +33,6 @@ Pod::Spec.new do |s| s.dependency "ReactCommon/turbomodule/core" end - s.dependency 'SCGateway', '4.0.2' + s.dependency 'SCGateway', '4.1.1' s.dependency 'SCLoans', '3.1.1' end