I am trying to port an iOS app over to React Native.
In this iOS app, one of the functions that needs to be done is to integrate it with a PayPal library (which is currently deprecated - we want to move away from it at some point later this year, but do not have the resources to do so now).
All we're doing with this library is obtaining a unique code from PayPal - that requires a View Controller to pop up, accept client credentials and return a code giving access.
I am extremely new to Objective-C.
I've got this so far (note: I have not included all the methods/properties but can include any missing):
COMPLETE PaypalSdk.h and PaypalSdk.m are at the bottom now
I am basing this off of this library:
https://github.com/paypal/PayPal-iOS-SDK/blob/master/SampleApp/PayPal-iOS-SDK-Sample-App/ZZMainViewController.m
And this documentation:
https://github.com/paypal/PayPal-iOS-SDK/blob/master/docs/profile_sharing_mobile.md
However when trying what I am above, I get the following error:
How exactly should I resolve this? It seems to need a View Controller but I'm not totally sure how to launch one from React Native in this context.
All we're trying to get is the shared profile information.
Here is one of the stack traces:
callstack: ( 0 CoreFoundation 0x00007fff23c7127e __exceptionPreprocess + 350 1 libobjc.A.dylib 0x00007fff513fbb20 objc_exception_throw + 48 2 UIKitCore 0x00007fff47a25b1a -[UIViewController _presentViewController:withAnimationController:completion:] + 5247 3 UIKitCore 0x00007fff47a2801b __63-[UIViewController _presentViewController:animated:completion:]_block_invoke + 98 4 UIKitCore 0x00007fff47a28533 -[UIViewController _performCoordinatedPresentOrDismiss:animated:] + 511 5 UIKitCore 0x00007fff47a27f79 -[UIViewController _presentViewController:animated:completion:] + 187 6 UIKitCore 0x00007fff47a281e0 -[UIViewController presentViewController:animated:completion:] + 150 7 myappname 0x000000010f92f8ac -[PaypalSdk getUserAuthorizationForProfileSharing] + 348 8 myappname 0x000000010f92fd99 -[PaypalSdk generateCode:] + 233 9 CoreFoundation 0x00007fff23c7820c __invoking___ + 140 10 CoreFoundation 0x00007fff23c753af -[NSInvocation invoke] + 319 11 CoreFoundation 0x00007fff23c75684 -[NSInvocation invokeWithTarget:] + 68 12 myappname 0x000000010f6e3902 -[RCTModuleMethod invokeWithBridge:module:arguments:] + 2658 13 myappname 0x000000010f6e7a37 _ZN8facebook5reactL11invokeInnerEP9RCTBridgeP13RCTModuleDatajRKN5folly7dynamicE + 791 14 myappname 0x000000010f6e7543 _ZZN8facebook5react15RCTNativeModule6invokeEjON5folly7dynamicEiENK3$_0clEv + 131 15 myappname 0x000000010f6e74b9 ___ZN8facebook5react15RCTNativeModule6invokeEjON5folly7dynamicEi_block_invoke + 25 16 libdispatch.dylib 0x0000000110caddd4 _dispatch_call_block_and_release + 12 17 libdispatch.dylib 0x0000000110caed48 _dispatch_client_callout + 8 18 libdispatch.dylib 0x0000000110cb55ef _dispatch_lane_serial_drain + 788 19 libdispatch.dylib 0x0000000110cb617f _dispatch_lane_invoke + 422 20 libdispatch.dylib 0x0000000110cc1a4e _dispatch_workloop_worker_thread + 719 21 libsystem_pthread.dylib 0x00007fff5246371b _pthread_wqthread + 290 22 libsystem_pthread.dylib 0x00007fff5246357b start_wqthread + 15)
Here is my complete PayPalSdk.m file:
#import <PayPal-iOS-SDK/PayPalMobile.h>#import <PayPal-iOS-SDK/PayPalConfiguration.h>#import <PayPal-iOS-SDK/PayPalOAuthScopes.h>#import <PayPal-iOS-SDK/PayPalProfileSharingViewController.h>#import <QuartzCore/QuartzCore.h>#import "PaypalSdk.h"@interface PaypalSdk ()@property(nonatomic, strong, readwrite) IBOutlet UIButton *payNowButton;@property(nonatomic, strong, readwrite) IBOutlet UIButton *payFutureButton;@property(nonatomic, strong, readwrite) IBOutlet UIView *successView;@property(nonatomic, strong, readwrite) PayPalConfiguration *payPalConfig;@end@implementation PaypalSdk#define kPayPalEnvironment PayPalEnvironmentProduction//int *REQUEST_CODE_PROFILE_SHARING = 3;- (void)viewDidLoad { [super viewDidLoad]; self.title = @"Pinyada PayPal"; // Set up payPalConfig self.payPalConfig = [[PayPalConfiguration alloc] init]; self.payPalConfig.acceptCreditCards = NO; self.payPalConfig.merchantName = @"Pinyada PayPal"; self.payPalConfig.merchantPrivacyPolicyURL = [NSURL URLWithString:@"https://www.paypal.com/webapps/mpp/ua/privacy-full"]; self.payPalConfig.merchantUserAgreementURL = [NSURL URLWithString:@"https://www.paypal.com/webapps/mpp/ua/useragreement-full"]; NSLog(@"PayPal iOS SDK version: %@", [PayPalMobile libraryVersion]);}- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {#warning "Enter your credentials" [PayPalMobile initializeWithClientIdsForEnvironments:@{PayPalEnvironmentProduction : @"PayPalProductionID", PayPalEnvironmentSandbox : @"YOUR_CLIENT_ID_FOR_SANDBOX"}]; return YES;}/*- (void)generateCode:()code {NSLog(@"Test");}*/- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // Start out working with the mock environment. When you are ready, switch to PayPalEnvironmentProduction. [PayPalMobile preconnectWithEnvironment:PayPalEnvironmentProduction];}- (IBAction)getUserAuthorizationForProfileSharing:(id)sender { NSSet *scopeValues = [NSSet setWithArray:@[kPayPalOAuth2ScopeOpenId, kPayPalOAuth2ScopeEmail, kPayPalOAuth2ScopeAddress, kPayPalOAuth2ScopePhone]]; PayPalProfileSharingViewController *profileSharingPaymentViewController = [[PayPalProfileSharingViewController alloc] initWithScopeValues:scopeValues configuration:self.payPalConfig delegate:self]; [self presentViewController:profileSharingPaymentViewController animated:YES completion:nil];}- (IBAction)obtainConsent { // Choose whichever scope-values apply in your case. See `PayPalOAuthScopes.h` for a complete list of available scope-values. NSSet *scopeValues = [NSSet setWithArray:@[kPayPalOAuth2ScopeOpenId, kPayPalOAuth2ScopeEmail, kPayPalOAuth2ScopeAddress, kPayPalOAuth2ScopePhone]]; PayPalProfileSharingViewController *psViewController; NSLog(@"PS VIEW CONTROLLER"); NSLog(psViewController); psViewController = [[PayPalProfileSharingViewController alloc] initWithScopeValues:scopeValues configuration:self.payPalConfig delegate:self];// Access the root view controller UIViewController *rootviewcontroller= [UIApplication sharedApplication].keyWindow.rootViewController; // Present the PayPalProfileSharingViewController [ rootviewcontroller presentViewController:psViewController animated:YES completion:nil];}- (void)userDidCancelPayPalProfileSharingViewController:(PayPalProfileSharingViewController *)profileSharingViewController { // User cancelled login. Dismiss the PayPalProfileSharingViewController, breathe deeply. [self dismissViewControllerAnimated:YES completion:nil];}- (void)payPalProfileSharingViewController:(PayPalProfileSharingViewController *)profileSharingViewController userDidLogInWithAuthorization:(NSDictionary *)profileSharingAuthorization { // The user has successfully logged into PayPal, and has consented to profile sharing. NSLog(@"REACT NATIVE ENV test"); // Be sure to dismiss the PayPalProfileSharingViewController. [self dismissViewControllerAnimated:YES completion:nil];}RCT_EXPORT_MODULE()RCT_EXPORT_METHOD(generateCode: (RCTResponseSenderBlock)callback) { [PayPalMobile initializeWithClientIdsForEnvironments:@{PayPalEnvironmentProduction : @"PayPalProductionID", PayPalEnvironmentSandbox : @"YOUR_CLIENT_ID_FOR_SANDBOX"}]; [self obtainConsent]; NSLog(@"REACT NATIVE ENV test"); //code = @"this is a test!"; // TODO: Implement some actually useful functionality callback(@[[NSNull null], @"test"]);}@end
And here is my complete PaypalSdk.h file:
#import "RCTBridgeModule.h"#import "PayPalMobile.h"@interface PaypalSdk : UIViewController <RCTBridgeModule, PayPalProfileSharingDelegate>@property(nonatomic, strong, readwrite) NSString *environment;@property(nonatomic, strong, readwrite) NSString *resultText;@property(nonatomic, strong) UIWindow *window;@property(nonatomic, strong) UIViewController *rootViewController;@end