无法在 SwiftUI 中实现 Apple Pay
Unable to implement Apple Pay in SwiftUI
我正在尝试在我的 SwiftUI 应用程序中实施 Apple Pay,但我一直无法显示按钮。
我已经通过 UIViewRepresentable
做到了
import SwiftUI
import UIKit
import PassKit
import Foundation
struct ApplePayButton: UIViewRepresentable {
func makeCoordinator() -> Coordinator {
Coordinator()
}
func updateUIView(_ uiView: PKPaymentButton, context: Context) {
}
func makeUIView(context: Context) -> PKPaymentButton {
let paymentButton = PKPaymentButton(paymentButtonType: .plain, paymentButtonStyle: .black)
return paymentButton
}
class Coordinator: NSObject, PKPaymentAuthorizationViewControllerDelegate {
func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
//
}
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 = "EUR",
countryCode: String = "AT",
merchantID: String = "c.c.c",
paymentNetworks: [PKPaymentNetwork] = [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
}
}
我不想使用 PKPaymentAuthorizationController
因为我想使用本机按钮。
当我点击按钮时出现这个错误:
[General] Payment request is invalid: Error Domain=PKPassKitErrorDomain Code=1 "Invalid in-app payment request" UserInfo={NSLocalizedDescription=Invalid in-app payment request, NSUnderlyingError=0x600003aeebb0 {Error Domain=PKPassKitErrorDomain Code=1 "PKPaymentRequest must contain an NSArray property 'paymentSummaryItems' of at least 1 valid objects of class PKPaymentSummaryItem" UserInfo={NSLocalizedDescription=PKPaymentRequest must contain an NSArray property 'paymentSummaryItems' of at least 1 valid objects of class PKPaymentSummaryItem}}}
查看:
struct PaymentView: View {
@Environment(\.presentationMode) private var presentationMode
@ObservedObject var requestViewModel: RequestViewModel
var applePayManager = ApplePayManager(items: [
PKPaymentSummaryItem(label: "Some Product", amount: 9.99)
])
var body: some View {
NavigationView {
VStack {
Text("By paying you agree to give the package to transporter.")
// requestViewModel.respondToRequest(status: button.status)
ApplePayButton()
.frame(width: 228, height: 40, alignment: .center)
.onTapGesture {
applePayManager.paymentViewController()
}
}
.navigationBarTitle("Payment")
.navigationBarItems(trailing: Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
Text("Done")
})
}
}
}
我做错了什么?
以防其他人像我一样挣扎:这是完整的代码。
import Foundation
import PassKit
class PaymentHandler: NSObject, ObservableObject {
func startPayment(paymentSummaryItems: [PKPaymentSummaryItem]) {
// Create our payment request
let paymentRequest = PKPaymentRequest()
paymentRequest.paymentSummaryItems = paymentSummaryItems
paymentRequest.merchantIdentifier = "merchant.de.xxx"
paymentRequest.merchantCapabilities = .capability3DS
paymentRequest.countryCode = "AT"
paymentRequest.currencyCode = "EUR"
paymentRequest.requiredShippingContactFields = [.phoneNumber, .emailAddress]
paymentRequest.supportedNetworks = [.masterCard, .visa]
// Display our payment request
let paymentController = PKPaymentAuthorizationController(paymentRequest: paymentRequest)
paymentController.delegate = self
paymentController.present(completion: { (presented: Bool) in })
}
}
/**
PKPaymentAuthorizationControllerDelegate conformance.
*/
extension PaymentHandler: PKPaymentAuthorizationControllerDelegate {
func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, completion: @escaping (PKPaymentAuthorizationStatus) -> Void) {
completion(.success)
print("paymentAuthorizationController completion(.success)")
}
func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) {
print("DidFinish")
}
func paymentAuthorizationControllerWillAuthorizePayment(_ controller: PKPaymentAuthorizationController) {
print("WillAuthorizePayment")
}
}
struct PaymentButton: UIViewRepresentable {
func updateUIView(_ uiView: PKPaymentButton, context: Context) { }
func makeUIView(context: Context) -> PKPaymentButton {
return PKPaymentButton(paymentButtonType: .plain, paymentButtonStyle: .automatic)
}
}
在视图中使用它:
PaymentButton()
.frame(width: 228, height: 40, alignment: .center)
.onTapGesture {
paymentHandler.startPayment(paymentSummaryItems: paymentSummaryItems)
}
我正在尝试在我的 SwiftUI 应用程序中实施 Apple Pay,但我一直无法显示按钮。
我已经通过 UIViewRepresentable
import SwiftUI
import UIKit
import PassKit
import Foundation
struct ApplePayButton: UIViewRepresentable {
func makeCoordinator() -> Coordinator {
Coordinator()
}
func updateUIView(_ uiView: PKPaymentButton, context: Context) {
}
func makeUIView(context: Context) -> PKPaymentButton {
let paymentButton = PKPaymentButton(paymentButtonType: .plain, paymentButtonStyle: .black)
return paymentButton
}
class Coordinator: NSObject, PKPaymentAuthorizationViewControllerDelegate {
func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
//
}
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 = "EUR",
countryCode: String = "AT",
merchantID: String = "c.c.c",
paymentNetworks: [PKPaymentNetwork] = [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
}
}
我不想使用 PKPaymentAuthorizationController
因为我想使用本机按钮。
当我点击按钮时出现这个错误:
[General] Payment request is invalid: Error Domain=PKPassKitErrorDomain Code=1 "Invalid in-app payment request" UserInfo={NSLocalizedDescription=Invalid in-app payment request, NSUnderlyingError=0x600003aeebb0 {Error Domain=PKPassKitErrorDomain Code=1 "PKPaymentRequest must contain an NSArray property 'paymentSummaryItems' of at least 1 valid objects of class PKPaymentSummaryItem" UserInfo={NSLocalizedDescription=PKPaymentRequest must contain an NSArray property 'paymentSummaryItems' of at least 1 valid objects of class PKPaymentSummaryItem}}}
查看:
struct PaymentView: View {
@Environment(\.presentationMode) private var presentationMode
@ObservedObject var requestViewModel: RequestViewModel
var applePayManager = ApplePayManager(items: [
PKPaymentSummaryItem(label: "Some Product", amount: 9.99)
])
var body: some View {
NavigationView {
VStack {
Text("By paying you agree to give the package to transporter.")
// requestViewModel.respondToRequest(status: button.status)
ApplePayButton()
.frame(width: 228, height: 40, alignment: .center)
.onTapGesture {
applePayManager.paymentViewController()
}
}
.navigationBarTitle("Payment")
.navigationBarItems(trailing: Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
Text("Done")
})
}
}
}
我做错了什么?
以防其他人像我一样挣扎:这是完整的代码。
import Foundation
import PassKit
class PaymentHandler: NSObject, ObservableObject {
func startPayment(paymentSummaryItems: [PKPaymentSummaryItem]) {
// Create our payment request
let paymentRequest = PKPaymentRequest()
paymentRequest.paymentSummaryItems = paymentSummaryItems
paymentRequest.merchantIdentifier = "merchant.de.xxx"
paymentRequest.merchantCapabilities = .capability3DS
paymentRequest.countryCode = "AT"
paymentRequest.currencyCode = "EUR"
paymentRequest.requiredShippingContactFields = [.phoneNumber, .emailAddress]
paymentRequest.supportedNetworks = [.masterCard, .visa]
// Display our payment request
let paymentController = PKPaymentAuthorizationController(paymentRequest: paymentRequest)
paymentController.delegate = self
paymentController.present(completion: { (presented: Bool) in })
}
}
/**
PKPaymentAuthorizationControllerDelegate conformance.
*/
extension PaymentHandler: PKPaymentAuthorizationControllerDelegate {
func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, completion: @escaping (PKPaymentAuthorizationStatus) -> Void) {
completion(.success)
print("paymentAuthorizationController completion(.success)")
}
func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) {
print("DidFinish")
}
func paymentAuthorizationControllerWillAuthorizePayment(_ controller: PKPaymentAuthorizationController) {
print("WillAuthorizePayment")
}
}
struct PaymentButton: UIViewRepresentable {
func updateUIView(_ uiView: PKPaymentButton, context: Context) { }
func makeUIView(context: Context) -> PKPaymentButton {
return PKPaymentButton(paymentButtonType: .plain, paymentButtonStyle: .automatic)
}
}
在视图中使用它:
PaymentButton()
.frame(width: 228, height: 40, alignment: .center)
.onTapGesture {
paymentHandler.startPayment(paymentSummaryItems: paymentSummaryItems)
}