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:
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
So you need to access the root view controller and then call presentViewController
on the same. Something like below should do the trick:
- (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;
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];
}
I haven't tried this so please check and let me know if this works. Otherwise find a view on which you can present the view controller.
Updating the answer based on the interaction with the OP:
Do not use that SDK. It is very old and deprecated.
If you need a native SDK to process payments with PayPal, you can use express checkout via Braintree. It also requires a web service of your own: https://developer.paypal.com/docs/accept-payments/express-checkout/ec-braintree-sdk/get-started/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.