Внедрение Apple Pay с SwiftUI - PullRequest
2 голосов
/ 20 марта 2020

Я впервые работаю с 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)
}
...