Skip to content

Commit

Permalink
Refactor ChoosePaymentMethodViewModel
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrei Solovev committed Feb 17, 2024
1 parent 483a69b commit 7a2d7d2
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 104 deletions.
4 changes: 2 additions & 2 deletions ExampleApp/Resources/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ You can present via either Storyboard or Code and you can see the code in the Ex
</connections>
</tableView>
<navigationItem key="navigationItem" title="Setup" id="FXz-KA-zGe">
<barButtonItem key="leftBarButtonItem" title="a" id="KNk-gK-jWw">
<barButtonItem key="leftBarButtonItem" title="Preset" id="KNk-gK-jWw">
<connections>
<action selector="showPresetChooser:" destination="9af-Wv-9QW" id="sEa-gg-XCo"/>
</connections>
Expand Down Expand Up @@ -1401,7 +1401,7 @@ You can present via either Storyboard or Code and you can see the code in the Ex
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="secondarySystemBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
Expand Down
73 changes: 40 additions & 33 deletions ExampleApp/Views/ProductDetailViewController.swift
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import UIKit
import OmiseSDK

class ProductDetailViewController: BaseViewController {
private let publicKey = LocalConfig.default.publicKey

private var capability: Capability?

override func viewDidLoad() {
super.viewDidLoad()
setupClient()
extension ProductDetailViewController: ChoosePaymentMethodDelegate {
func paymentCompleteWithResult(_ result: PaymentResult) {
switch result {
default:
break
}
dismissForm()
print("payment complete with \(result)")
}
}

private func setupClient() {
let config = LocalConfig.default.configuration
let client = OmiseSDK(publicKey: publicKey, configuration: config).client
class ProductDetailViewController: BaseViewController {
let omiseSDK = OmiseSDK(publicKey: LocalConfig.default.publicKey,
configuration: LocalConfig.default.configuration)

client.capability { (result) in
private func loadCapability() {
omiseSDK.client.capability { (result) in
if case .success(let capability) = result {
self.capability = capability
print("Capability Country: \(capability.countryCode)")
}
}
Expand Down Expand Up @@ -69,39 +70,45 @@ class ProductDetailViewController: BaseViewController {
guard currentCodePathMode == .code else {
return
}
let creditCardFormController = CreditCardFormViewController.makeCreditCardFormViewController(withPublicKey: publicKey)
creditCardFormController.handleErrors = true
creditCardFormController.delegate = self
let navigationController = UINavigationController(rootViewController: creditCardFormController)
present(navigationController, animated: true, completion: nil)
// let creditCardFormController = CreditCardFormViewController.makeCreditCardFormViewController(withPublicKey: publicKey)
// creditCardFormController.handleErrors = true
// creditCardFormController.delegate = self
// let navigationController = UINavigationController(rootViewController: creditCardFormController)
// present(navigationController, animated: true, completion: nil)
}

@IBAction private func showCreditCardForm(_ sender: UIButton) {
guard currentCodePathMode == .code else {
return
}
let creditCardFormController = CreditCardFormViewController.makeCreditCardFormViewController(withPublicKey: publicKey)
creditCardFormController.handleErrors = true
creditCardFormController.delegate = self
show(creditCardFormController, sender: self)
// let creditCardFormController = CreditCardFormViewController.makeCreditCardFormViewController(withPublicKey: publicKey)
// creditCardFormController.handleErrors = true
// creditCardFormController.delegate = self
// show(creditCardFormController, sender: self)
}

@IBAction private func showModalPaymentCreator(_ sender: Any) {
guard currentCodePathMode == .code else {
return
}

let paymentMethods = usesCapabilityDataForPaymentMethods ? nil : allowedPaymentMethods
let choosePaymentMethodController = OmiseSDK(publicKey: publicKey)
.makeChoosePaymentMethodController(
allowedPaymentMethods: paymentMethods,
paymentAmount: paymentAmount,
paymentCurrency: paymentCurrencyCode) { [weak self] result in
print("Payment complete with \(result)")
self?.dismissForm()
}

present(choosePaymentMethodController, animated: true, completion: nil)
if usesCapabilityDataForPaymentMethods {
let viewController = omiseSDK.makeChoosePaymentMethodController(
amount: paymentAmount,
currency: paymentCurrencyCode,
delegate: self
)
present(viewController, animated: true, completion: nil)
} else {
let viewController = omiseSDK.makeChoosePaymentMethodController(
amount: paymentAmount,
currency: paymentCurrencyCode,
allowedPaymentMethods: allowedPaymentMethods,
showsCreditCardPayment: true,
delegate: self
)
present(viewController, animated: true, completion: nil)
}
}

@IBAction private func showCustomCreditCardForm(_ sender: Any) {
Expand Down
19 changes: 12 additions & 7 deletions OmiseSDK/ChoosePaymentMethodController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ protocol PaymentChooserControllerViewModel {
var onViewContextChanged: ([ChoosePaymentMethodController.ViewContext]) -> Void { get }
}

protocol PaymentChooserControllerDelegate: AnyObject {
}

/// swiftlint:disable:next type_body_length
class ChoosePaymentMethodController: UITableViewController {
struct ViewContext: Equatable {
Expand All @@ -19,15 +16,26 @@ class ChoosePaymentMethodController: UITableViewController {

let viewModel = ChoosePaymentMethodViewModel()

func reloadIfLoaded() {
func reloadIfViewIsLoaded() {
if isViewLoaded {
tableView.reloadData()
}
}

override func viewDidLoad() {
super.viewDidLoad()
viewModel.onViewContextChanged = { [weak self] _ in
self?.reloadIfViewIsLoaded()
}
tableView.rowHeight = 64
applyNavigationBarStyle()
setupNavigationItems()
}

private func setupViewModel() {
}

private func setupNavigationItems() {
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
navigationItem.rightBarButtonItem = UIBarButtonItem(
image: UIImage(omise: "Close"),
Expand All @@ -40,9 +48,6 @@ class ChoosePaymentMethodController: UITableViewController {
if #available(iOSApplicationExtension 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
}

applyNavigationBarStyle()
tableView.rowHeight = 64
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
Expand Down
77 changes: 40 additions & 37 deletions OmiseSDK/ChoosePaymentMethodViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,15 @@ class ChoosePaymentMethodViewModel {
typealias ViewContext = ChoosePaymentMethodController.ViewContext

var flowSession: PaymentCreatorFlowSession?
var showsCreditCardPayment = true
var paymentAmount: Int64 = 0
var paymentCurrency: String = ""

var completion: PaymentResultClosure = { _ in }
var usePaymentMethodsFromCapability: Bool = false {
didSet {
if usePaymentMethodsFromCapability {
loadCapabilities()
}
}
}
var client: Client? {
didSet {
if usePaymentMethodsFromCapability {
loadCapabilities()
}
}
}
var amount: Int64 = 0
var currency: String = ""

var allowedPaymentMethods: [SourceType] = [] {
didSet {
viewContexts = generateViewContexts(from: allowedPaymentMethods)
}
}
var usePaymentMethodsFromCapability = false
var allowedPaymentMethods: [SourceType] = []
var showsCreditCardPayment = false
var client: Client?
var completion: (PaymentResult) -> Void = { _ in }

var onViewContextChanged: ([ViewContext]) -> Void = { _ in }
private var viewContexts: [ViewContext] = [] {
Expand All @@ -48,35 +32,54 @@ class ChoosePaymentMethodViewModel {
return viewContexts[index]
}

func loadCapabilities() {
private func loadCapabilities() {
guard let client = client, usePaymentMethodsFromCapability else {
return
}

if let capability = client.latestLoadedCapability {
allowedPaymentMethods(from: capability)
client.capability { [weak self] _ in
self?.updateViewContexts()
}
client.capability { [weak self] result in
if let capability = try? result.get() {
self?.allowedPaymentMethods(from: capability)
}

if client.latestLoadedCapability != nil {
updateViewContexts()
}
}

func allowedPaymentMethods(from capability: Capability) {
showsCreditCardPayment = capability.cardPaymentMethod != nil

allowedPaymentMethods = capability.paymentMethods.compactMap {
SourceType(rawValue: $0.name)
func reload() {
if usePaymentMethodsFromCapability {
loadCapabilities()
}

updateViewContexts()
}
}

private extension ChoosePaymentMethodViewModel {
func generateViewContexts(from sourceTypes: [SourceType]) -> [ViewContext] {

func updateViewContexts() {
if usePaymentMethodsFromCapability {
guard let capability = client?.latestLoadedCapability else {
return
}

let capabilitySourceTypes = capability.paymentMethods.compactMap {
SourceType(rawValue: $0.name)
}

let showsCreditCard = capability.cardPaymentMethod != nil
print("showsCreditCard: \(showsCreditCard)")
self.viewContexts = generateViewContexts(from: capabilitySourceTypes, showsCreditCard: showsCreditCard)
} else {
print("2. showsCreditCard: \(showsCreditCardPayment)")
self.viewContexts = generateViewContexts(from: allowedPaymentMethods, showsCreditCard: showsCreditCardPayment)
}
}

func generateViewContexts(from sourceTypes: [SourceType], showsCreditCard: Bool) -> [ViewContext] {
var list = PaymentOption.from(sourceTypes)

if showsCreditCardPayment {
if showsCreditCard {
list.append(.creditCard)
}

Expand Down
2 changes: 1 addition & 1 deletion OmiseSDK/PaymentCreatorController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public class PaymentCreatorController: UINavigationController {
}

public func applyPaymentMethods(from capability: Capability) {
paymentChooserController.viewModel.allowedPaymentMethods(from: capability)
paymentChooserController.viewModel.usePaymentMethodsFromCapability = true
}

private func initializeWithPaymentChooserViewController(_ viewController: ChoosePaymentMethodController) {
Expand Down
20 changes: 15 additions & 5 deletions OmiseSDK/PaymentFlow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ public enum PaymentResult {
case cancel
}

public protocol ChoosePaymentMethodDelegate: AnyObject {
func paymentCompleteWithResult(_ result: PaymentResult)
}

public class PaymentFlow {
var completion: PaymentResultClosure = { _ in }
let client: Client
Expand All @@ -25,19 +29,25 @@ public class PaymentFlow {
/// - allowedPaymentMethods: List of Payment Methods to be presented in the list
/// - usePaymentMethodsFromCapability: If true then take payment methods from client.capability()
func createRootViewController(
allowedPaymentMethods: [SourceType],
allowedPaymentMethods: [SourceType] = [],
showsCreditCardPayment: Bool = true,
usePaymentMethodsFromCapability: Bool,
completion: @escaping PaymentResultClosure
delegate: ChoosePaymentMethodDelegate
) -> ChoosePaymentMethodController {
let rootViewController = ChoosePaymentMethodController()
rootViewController.addChild(PaymentFlowContainerController(self))
let viewModel = rootViewController.viewModel
viewModel.allowedPaymentMethods = allowedPaymentMethods
viewModel.paymentAmount = amount
viewModel.paymentCurrency = currency
viewModel.completion = completion
viewModel.showsCreditCardPayment = showsCreditCardPayment
viewModel.amount = amount
viewModel.currency = currency
viewModel.client = client
viewModel.usePaymentMethodsFromCapability = usePaymentMethodsFromCapability
viewModel.completion = { [weak delegate] result in
delegate?.paymentCompleteWithResult(result)
}
viewModel.reload()

return rootViewController
}
}
Expand Down
7 changes: 6 additions & 1 deletion OmiseSDK/Sources/OmiseAPI/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class Client {
/// - network: Optional network communication service is used for testing
/// - apiURL: Custom URL for Omise API Server is used for testing
/// - vaultURL: Custom URL for Omise Vault Server is used for testing
init(publicKey: String, network: NetworkServiceProtocol, apiURL: URL? = nil, vaultURL: URL? = nil) {
init(publicKey: String, network: NetworkServiceProtocol = NetworkService(), apiURL: URL? = nil, vaultURL: URL? = nil) {
self.publicKey = publicKey
self.network = network
self.customApiURL = apiURL
Expand Down Expand Up @@ -84,4 +84,9 @@ public class Client {
completion
)
}

/// Used for the test purposes
func setLatestLoadedCapability(_ capability: Capability) {
latestLoadedCapability = capability
}
}
Loading

0 comments on commit 7a2d7d2

Please sign in to comment.