Я впервые работаю с PassKit и SwiftUI над большим проектом. Я пытаюсь внедрить Apple Pay SwiftUI, и поскольку пока нет собственного способа сделать это, я попытался обернуть PKPaymentAuthorizationViewController в UIViewControllerRepresentable, но я не уверен, правильно ли я это делаю.
Вид отображается правильно и, кажется, работает при нажатии на него, чтобы заплатить. Я управляю показом окна, связывая представление с bool isPresentingApplePay (см. Ниже). Проблемы случаются, когда окно должно быть закрыто. Нажатие на кнопку cancel
не отменяет вид; иногда он даже не вызывает функцию делегата paymentAuthorizationViewControllerDidFini sh. То же самое происходит после отправки платежа. Иногда вызывается делегат didFini sh, но представление не отклоняется. Я попытался передать переменную привязки isPresentingApplePay и установить ее в false из didFini sh, но она ничего не делает. Единственный способ заставить вид исчезнуть - это нажать на любую часть за пределами окна оплаты Apple.
Кто-нибудь знает, что я делаю не так? Есть ли что-то, что я полностью пропускаю
Я получаю окно Apple Pay, чтобы оно отображалось правильно при нажатии кнопки, связывая представление под if statement
Вот моя оболочка PKPaymentAuthorizationViewController:
import Foundation
import PassKit
import SwiftUI
struct ApplePayController: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentationMode
@EnvironmentObject var userData: UserData
@Binding var purchase: Purchase
@Binding var isPresenting: Bool
let items: [PKPaymentSummaryItem]
func updateUIViewController(_ uiViewController: PKPaymentAuthorizationViewController, context: Context) {
}
typealias UIViewControllerType = PKPaymentAuthorizationViewController
func makeUIViewController(context: Context) -> PKPaymentAuthorizationViewController {
let applePayManager = ApplePayManager(items: items)
let apm = applePayManager.paymentViewController()!
apm.delegate = context.coordinator
return apm
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, PKPaymentAuthorizationViewControllerDelegate {
var parent: ApplePayController
init(_ parent: ApplePayController) {
self.parent = parent
}
func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
controller.dismiss(animated: true) {
self.parent.isPresenting = false
}
}
func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
print("did authorize payment")
}
func paymentAuthorizationViewControllerWillAuthorizePayment(_ controller: PKPaymentAuthorizationViewController) {
print("Will authorize payment")
}
}
class ApplePayManager: NSObject {
let currencyCode: String
let countryCode: String
let merchantID: String
let paymentNetworks: [PKPaymentNetwork]
let items: [PKPaymentSummaryItem]
init(items: [PKPaymentSummaryItem],
currencyCode: String = "USD",
countryCode: String = "US",
merchantID: String = "xxx.merchant.xxx",
paymentNetworks: [PKPaymentNetwork] = [PKPaymentNetwork.amex, PKPaymentNetwork.masterCard, PKPaymentNetwork.visa]) {
self.items = items
self.currencyCode = currencyCode
self.countryCode = countryCode
self.merchantID = merchantID
self.paymentNetworks = paymentNetworks
}
func paymentViewController() -> PKPaymentAuthorizationViewController? {
if PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: paymentNetworks) {
let request = PKPaymentRequest()
request.currencyCode = self.currencyCode
request.countryCode = self.countryCode
request.supportedNetworks = paymentNetworks
request.merchantIdentifier = self.merchantID
request.paymentSummaryItems = items
request.merchantCapabilities = [.capabilityCredit, .capabilityDebit]
return PKPaymentAuthorizationViewController(paymentRequest: request)
}
return nil
}
}
}
и вот как я показываю это в своем UIView:
if isPresentingApplePay {
ApplePayController(purchase: self.$currentOrder.purchase, isPresenting: $isPresentingApplePay, items: self.createOrder(with: self.currentOrder.purchase)).environmentObject(self.userData)
}