Bug 30350 - Could not initialize an instance of the type PassKit.PKPaymentAuthorizationViewController
Summary: Could not initialize an instance of the type PassKit.PKPaymentAuthorizationVi...
Status: RESOLVED ANSWERED
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: XI 8.10
Hardware: PC Mac OS
: Normal normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2015-05-22 10:27 UTC by John Miller [MSFT]
Modified: 2015-05-28 09:32 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED ANSWERED

Description John Miller [MSFT] 2015-05-22 10:27:10 UTC
**Overview:**

   When trying to implement Apple Pay, creating an instance of PKPaymentAuthorizationViewController fails with an error message. 

**Steps to Reproduce:**

   1. Youll need an App ID/Certificate/Provision setup that allows Apple Pay entitlements. 
   2. Run the attached sample on a device
   3. Press the "Buy with Apple Pay" button.

   Line 41 of "ViewController.cs" needs to modified to match your merchant ID. 
   The Entitlements.plist also must be modified to match your merchant ID
   The Bundle ID of the project needs to be set to whatever you create for the provision.

**Actual Results:**

   Could not initialize an instance of the type 'PassKit.PKPaymentAuthorizationViewController': the native 'initWithPaymentRequest:' method returned nil.
It is possible to ignore this condition by setting MonoTouch.ObjCRuntime.Class.ThrowOnInitFailure to false. (System.Exception)
  at Foundation.NSObject.InitializeHandle (IntPtr handle, System.String initSelector) [0x000b0] in /Users/builder/data/lanes/1503/6481535e/source/maccore/src/Foundation/NSObject2.cs:470 
  at PassKit.PKPaymentAuthorizationViewController..ctor (PassKit.PKPaymentRequest request) [0x00027] in /Users/builder/data/lanes/1503/6481535e/source/maccore/src/build/ios/native/PassKit/PKPaymentAuthorizationViewController.g.cs:89 
  at ApplePayDemo.ViewController.UIButton3_TouchUpInside (UIKit.UIButton sender) [0x000c6] in /Users/johnmiller/Downloads/ApplePayDemo/ViewController.cs:74 
  at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Users/builder/data/lanes/1503/6481535e/source/maccore/src/UIKit/UIApplication.cs:63 
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0001c] in /Users/builder/data/lanes/1503/6481535e/source/maccore/src/UIKit/UIApplication.cs:46 
  at ApplePayDemo.Application.Main (System.String[] args) [0x00008] in /Users/johnmiller/Downloads/ApplePayDemo/Main.cs:12 

**Expected Results:**

   No exceptions.

**Build Date & Platform:**

   XI 8.10
   iOS 8.2
Comment 4 Sebastien Pouliot 2015-05-22 10:43:29 UTC
Does `PKPaymentAuthorizationViewController.CanMakePayments` returns `true` ?

Also the (pay) network should be tested too, e.g.

	PKPaymentAuthorizationViewController.CanMakePaymentsUsingNetworks (request.SupportedNetworks);

The application must call them before using the UI / feature. IOW if something is wrong* then a `nil` view controller is _normal_ (that's what Apple does).

* e.g. I can't use ApplePay from Canada. Application needs to check (above call) in order for their apps to work for me (and most of the world).
Comment 5 John Miller [MSFT] 2015-05-26 10:00:55 UTC
@Sebastien,

Yes, you're correct. CanMakePayments returns false so it seems the nil controller is expected. If this same app is tested on supported hardware/areas I assume the exceptions from comment #3 will happen. 

Unable to locate the block to delegate conversion
method for the method
Mobile.iOS.PaymentViewController.PaymentAuthorizationViewControllerDidAuthorizePayment's
Comment 6 Sebastien Pouliot 2015-05-27 11:11:47 UTC
I cannot duplicate it (wrong location) but the issue is that code:

	[Export("paymentAuthorizationViewController:didAuthorizePayment:completion:")]
	public void PaymentAuthorizationViewControllerDidAuthorizePayment(PKPaymentAuthorizationViewController controller, PKPayment payment, Action<PKPaymentAuthorizationStatus> completion)

^ The manually added export definition is incomplete. You cannot have have a Action<T> delegate without giving some instruction on how this can be called from ObjC. 

Normally our binding generator (e.g. `btouch`) handles this automagically, e.g.

void DidAuthorizePayment (PKPaymentAuthorizationViewController controller, PKPayment payment, [BlockProxy (typeof(Trampolines.NIDActionArity1V36))] Action<PKPaymentAuthorizationStatus> completion);

That [BlockProxy] is the glue required - and it's not trivially re-implemented. OTOH if you're export'ing this manually (in code) then the generator cannot help you.

You can avoid this by using `PKPaymentAuthorizationViewControllerDelegate` and implement `DidAuthorizePayment`. Since that code has been generated then the correct glue code is already present.
Comment 7 John Miller [MSFT] 2015-05-28 09:32:15 UTC
That was the issue, thanks Sebastien!