簡體   English   中英

應用程序試圖在 React Native Objective-C 擴展中的目標上呈現零模式視圖 controller

[英]Application tried to present a nil modal view controller on target in React Native Objective-C extension

我正在嘗試將 iOS 應用程序移植到 React Native。

在這個 iOS 應用程序中,需要完成的功能之一是將其與 PayPal 庫(目前已棄用 - 我們希望在今年晚些時候離開它,但沒有資源做所以現在)。

我們對這個庫所做的只是從 PayPal 獲取一個唯一代碼 - 這需要一個視圖 Controller 彈出,接受客戶端憑據並返回一個代碼來授予訪問權限。

我對 Objective-C非常陌生。

到目前為止我已經得到了這個(注意:我沒有包括所有的方法/屬性,但可以包括任何缺失的):

COMPLETE PaypalSdk.h 和 PaypalSdk.m 現在位於底部

我基於這個庫:

https://github.com/paypal/PayPal-iOS-SDK/blob/master/SampleApp/PayPal-iOS-SDK-Sample-App/ZZMainViewController.m

這個文檔:

https://github.com/paypal/PayPal-iOS-SDK/blob/master/docs/profile_sharing_mobile.md

但是,當嘗試我上面的內容時,我收到以下錯誤:

React Native 錯誤屏幕

我應該如何解決這個問題? 它似乎需要一個 View Controller 但我不完全確定如何在這種情況下從 React Native 啟動一個。

我們試圖獲得的只是共享的個人資料信息。

這是堆棧跟蹤之一:

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
)

這是我完整的 PayPalSdk.m 文件:

#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

這是我完整的 PaypalSdk.h 文件:

#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

所以你需要訪問根視圖 controller 然后調用presentViewController 像下面這樣的東西應該可以解決問題:

- (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];
}

我還沒有嘗試過,所以請檢查並讓我知道這是否有效。 否則,請找到一個視圖,您可以在該視圖上展示 controller 視圖。


根據與 OP 的交互更新答案:

  • 為此,必須使用 RCT 方法覆蓋與視圖相關的方法,並且需要在調用 generatecode RCT 方法之前調用它們。 這與根視圖 controller 一起似乎解決了這個問題。

不要使用那個 SDK。 它非常古老且已被棄用。

如果您需要本機 SDK 來使用 PayPal 處理付款,您可以通過 Braintree 使用快速結帳。 它還需要您自己的 web 服務: https://developer.paypal.com/docs/accept-payments/express-checkout/ec-braintree-tree-getd

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM