Amrit
4 years ago
41 changed files with 21 additions and 3499 deletions
-
348GME Remit.xcodeproj/project.pbxproj
-
23GME Remit/APIs/Router/APIRouter.swift
-
61GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Interactor/DomesticRemitInteractor.swift
-
22GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Interactor/DomesticRemitInteractorIO.swift
-
28GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Model/DomesticRemitModel.swift
-
23GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Model/DomesticRemitResponseModel.swift
-
23GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Model/RecipientNameModel.swift
-
36GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Model/Request/DomesticRemitRequestModel.swift
-
63GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Service/DomesticRemitService.swift
-
34GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Service/DomesticRemitServiceType.swift
-
16GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Module Interface/DomesticRemitModuleInterface.swift
-
134GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/Presenter/DomesticRemitPresenter.swift
-
48GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/View/Cell/DomesticBankListTableViewCell.swift
-
633GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/View/DomesticRemit.storyboard
-
490GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/View/DomesticRemitViewController.swift
-
292GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/View/ViewModel/DomesticRemitViewModel.swift
-
19GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/View/ViewModel/DomesticRemitViewModelInterface.swift
-
186GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/Wireframe/DomesticRemitWireframe.swift
-
24GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/Wireframe/DomesticRemitWireframeInputOutput.swift
-
40GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/Application Logic/Interactor/RecentHistoriesInteractor.swift
-
19GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/Application Logic/Interactor/RecentHistoriesInteractorIO.swift
-
35GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/Application Logic/Model/RecentRecipientModel.swift
-
21GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/Application Logic/Service/RecentHistoriesService.swift
-
16GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/Application Logic/Service/RecentHistoriesServiceType.swift
-
17GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/Module Interface/RecentHistoriesModuleInterface.swift
-
51GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/Presenter/RecentHistoriesPresenter.swift
-
23GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/View/Cell/RecentRecipientCell.swift
-
315GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/View/RecentHistories.storyboard
-
196GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/View/RecentHistoriesViewController.swift
-
104GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/View/ViewModel/RecentHistoriesViewModel.swift
-
14GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/View/ViewModel/RecentHistoriesViewModelInterface.swift
-
62GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/Wireframe/RecentHistoriesWireframe.swift
-
17GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/Wireframe/RecentHistoriesWireframeInputOutput.swift
-
10GME Remit/Modules/RemittanceModules/OverseasModules/SendMoneyReceipt/Application Logic/Service/SendMoneyReceiptService.swift
-
16GME Remit/Modules/RemittanceModules/OverseasModules/SendMoneyReceipt/User Interface/View/SendMoneyReceiptViewController.swift
-
9GME Remit/Modules/RemittanceModules/Shared/BalanceModel.swift
-
11GME Remit/Modules/RemittanceModules/TransactionHistoryModules/TransactionHistory/Application Logic/Interactor/TransactionHistoryInteractor.swift
-
16GME Remit/Modules/RemittanceModules/TransactionHistoryModules/TransactionHistory/Application Logic/Service/TransactionHistoryServiceType.swift
-
5GME Remit/Modules/RemittanceModules/TransactionHistoryModules/TransactionHistory/User Interface/View/TransactionHistoryViewController.swift
-
3GME Remit/Modules/RemittanceModules/TransactionHistoryModules/TransactionHistoryGroup/User Interface/View/TransactionHistoryGroupViewController.swift
-
17GME RemitTests/APITest.swift
@ -1,61 +0,0 @@ |
|||
// |
|||
// DomesticRemitInteractor.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
|
|||
class DomesticRemitInteractor { |
|||
|
|||
// MARK: Properties |
|||
|
|||
weak var output: DomesticRemitInteractorOutput? |
|||
private let service: DomesticRemitServiceType |
|||
|
|||
// MARK: Initialization |
|||
|
|||
init(service: DomesticRemitServiceType) { |
|||
self.service = service |
|||
} |
|||
|
|||
} |
|||
|
|||
// MARK: DomesticRemit interactor input interface |
|||
|
|||
extension DomesticRemitInteractor: DomesticRemitInteractorInput { |
|||
func fetchInformation() { |
|||
service.fetchInformation( |
|||
success: {self.output?.setModel(with: $0)}, |
|||
failure: {self.output?.setError(with: $0)} |
|||
) |
|||
} |
|||
|
|||
func getRecipientName(account: String, bankCode: String) { |
|||
service.getRecipientName( |
|||
account: account, |
|||
bankCode: bankCode, |
|||
success: {self.output?.setRecipientName(with:$0)}, |
|||
failure: {self.output?.setError(with: $0)} |
|||
) |
|||
} |
|||
|
|||
func fetchBalance(type: String, fintechUseNumber: String) { |
|||
service.fetchBalance( |
|||
type: type, |
|||
fintechUseNumber: fintechUseNumber, |
|||
success: {self.output?.setBalance(with: $0)}, |
|||
failure: {self.output?.setError(with: $0)} |
|||
) |
|||
} |
|||
|
|||
func send(with model: DomesticRemitRequestModel) { |
|||
service.send( |
|||
with: model, |
|||
success: {self.output?.setSendSuccess(with: $0)}, |
|||
failure: {self.output?.setError(with: $0)} |
|||
) |
|||
} |
|||
} |
@ -1,22 +0,0 @@ |
|||
// |
|||
// DomesticRemitInteractorIO.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
protocol DomesticRemitInteractorInput: class { |
|||
func fetchInformation() |
|||
func getRecipientName(account: String, bankCode: String) |
|||
func fetchBalance(type: String, fintechUseNumber: String) |
|||
func send(with model: DomesticRemitRequestModel) |
|||
} |
|||
|
|||
protocol DomesticRemitInteractorOutput: class { |
|||
func setModel(with model: DomesticRemitModel) |
|||
func setRecipientName(with model: RecipientNameModel) |
|||
func setBalance(with model: BalanceModel) |
|||
func setError(with error: Error) |
|||
func setSendSuccess(with model: ResponseContainerObject<DomesticRemitResponseModel>) |
|||
} |
@ -1,28 +0,0 @@ |
|||
// |
|||
// DemesticRemitModel.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import ObjectMapper |
|||
|
|||
struct DomesticRemitModel: Mappable { |
|||
|
|||
var accounts: [Account]? |
|||
var banks: [BankInformation]? |
|||
var serviceFee: String? |
|||
var serviceFeeWallet: String? |
|||
|
|||
init?(map: Map) { |
|||
|
|||
} |
|||
|
|||
mutating func mapping(map: Map) { |
|||
accounts <- map["accounts"] |
|||
banks <- map["banks"] |
|||
serviceFee <- map["servicefee"] |
|||
serviceFeeWallet <- map["servicefee_wallet"] |
|||
} |
|||
} |
@ -1,23 +0,0 @@ |
|||
// |
|||
// DomesticRemitResponse.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 20/09/2019. |
|||
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import ObjectMapper |
|||
|
|||
struct DomesticRemitResponseModel: Mappable { |
|||
var customerId: String? |
|||
var transactionID: String? |
|||
|
|||
init?(map: Map) { |
|||
|
|||
} |
|||
|
|||
mutating func mapping(map: Map) { |
|||
customerId <- map["CustomerId"] |
|||
transactionID <- map["TranNo"] |
|||
} |
|||
} |
@ -1,23 +0,0 @@ |
|||
// |
|||
// RecipientNameModel.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import ObjectMapper |
|||
|
|||
struct RecipientNameModel: Mappable { |
|||
var name: String? |
|||
var mobile: String? |
|||
|
|||
init?(map: Map) { |
|||
|
|||
} |
|||
|
|||
mutating func mapping(map: Map) { |
|||
name <- map["RecipientName"] |
|||
mobile <- map["RecipientPhone"] |
|||
} |
|||
} |
@ -1,36 +0,0 @@ |
|||
// |
|||
// DomesticRemitRequestModel.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 19/09/2019. |
|||
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
struct DomesticRemitRequestModel { |
|||
let customerID: String |
|||
let fintechID: String |
|||
let accountID: String |
|||
let sendAmount: String |
|||
let bankCode: String |
|||
let accountNumber: String |
|||
let type: String |
|||
let name: String |
|||
let mobile: String |
|||
let isUseBiometric: Bool |
|||
var password: String |
|||
} |
|||
|
|||
extension DomesticRemitRequestModel: OTPProtocol { |
|||
var otpAmount: String? { |
|||
return sendAmount |
|||
} |
|||
|
|||
var otpAccountID: String? { |
|||
return accountID |
|||
} |
|||
} |
|||
|
|||
protocol OTPProtocol { |
|||
var otpAmount: String? { get } |
|||
var otpAccountID: String? { get } |
|||
} |
@ -1,63 +0,0 @@ |
|||
// |
|||
// DomesticRemitService.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
|
|||
class DomesticRemitService: DomesticRemitServiceType { |
|||
func fetchInformation( |
|||
success: @escaping (DomesticRemitModel) -> Void, |
|||
failure: @escaping (Error) -> Void |
|||
) { |
|||
APIRouter.domesticRemitStart.json(success: success, failure: failure) |
|||
} |
|||
|
|||
func getRecipientName( |
|||
account: String, |
|||
bankCode: String, |
|||
success: @escaping (RecipientNameModel) -> Void, |
|||
failure: @escaping (Error) -> Void |
|||
) { |
|||
APIRouter.fetchRecipientName(bankCode: bankCode, accountNumber: account) |
|||
.json(success: success, failure: failure) |
|||
|
|||
} |
|||
|
|||
func fetchBalance( |
|||
type: String, |
|||
fintechUseNumber: String, |
|||
success: @escaping (BalanceModel) -> Void, |
|||
failure: @escaping (Error) -> Void |
|||
) { |
|||
APIRouter.fetchBalace( |
|||
type: type, |
|||
fintechUseNumber: fintechUseNumber |
|||
).json(success: success, failure: failure) |
|||
} |
|||
|
|||
func send( |
|||
with model: DomesticRemitRequestModel, |
|||
success: @escaping (ResponseContainerObject<DomesticRemitResponseModel>) -> Void, |
|||
failure: @escaping (Error) -> Void |
|||
) { |
|||
APIRouter.sendDomesticRemit(model: model) |
|||
.request( |
|||
success: {(response: ResponseContainerObject<DomesticRemitResponseModel>) in |
|||
if response.errorCode != "0" { |
|||
let error = NSError( |
|||
domain: "Network", |
|||
code: 0, |
|||
message: response.message ?? "Failed Send Money" |
|||
) |
|||
failure(error) |
|||
} |
|||
success(response) |
|||
}, |
|||
failure: failure |
|||
) |
|||
} |
|||
} |
@ -1,34 +0,0 @@ |
|||
// |
|||
// DomesticRemitServiceType.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
protocol DomesticRemitServiceType: class { |
|||
func fetchInformation( |
|||
success: @escaping (DomesticRemitModel) -> Void, |
|||
failure: @escaping (Error) -> Void |
|||
) |
|||
|
|||
func getRecipientName( |
|||
account: String, |
|||
bankCode: String, |
|||
success: @escaping (RecipientNameModel) -> Void, |
|||
failure: @escaping (Error) -> Void |
|||
) |
|||
|
|||
func fetchBalance( |
|||
type: String, |
|||
fintechUseNumber: String, |
|||
success: @escaping (BalanceModel) -> Void, |
|||
failure: @escaping (Error) -> Void |
|||
) |
|||
|
|||
func send( |
|||
with model: DomesticRemitRequestModel, |
|||
success: @escaping (ResponseContainerObject<DomesticRemitResponseModel>) -> Void, |
|||
failure: @escaping (Error) -> Void |
|||
) |
|||
} |
@ -1,16 +0,0 @@ |
|||
// |
|||
// DomesticRemitModuleInterface.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
protocol DomesticRemitModuleInterface: class { |
|||
func fetchInformation() |
|||
func showTablePresenter(type: DomesticRemitPresenter.ShowType) |
|||
func getRecipientName(account: String, bankCode: String) |
|||
func fetchBalance(type: String, fintechUseNumber: String) |
|||
func send(with model: DomesticRemitRequestModel) |
|||
func goReceipt(with model: DomesticRemitResponseModel) |
|||
} |
@ -1,134 +0,0 @@ |
|||
// |
|||
// DomesticRemitPresenter.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
|
|||
class DomesticRemitPresenter { |
|||
|
|||
// MARK: Properties |
|||
weak var viewModel: DomesticRemitViewModelInterface? |
|||
var interactor: DomesticRemitInteractorInput? |
|||
var wireframe: DomesticRemitWireframeInput? |
|||
|
|||
private var banks: [BankInformation]? |
|||
private var accounts: [Account]? |
|||
|
|||
private var domesticRequestModel: DomesticRemitRequestModel? |
|||
|
|||
enum ShowType: Int { |
|||
case histories = 0 |
|||
case banks |
|||
case autodebit |
|||
} |
|||
} |
|||
|
|||
// MARK: DomesticRemit module interface |
|||
extension DomesticRemitPresenter: DomesticRemitModuleInterface { |
|||
func fetchInformation() { |
|||
viewModel?.progress(isShow: true) |
|||
interactor?.fetchInformation() |
|||
} |
|||
|
|||
func showTablePresenter(type: ShowType) { |
|||
switch type { |
|||
case .histories: |
|||
wireframe?.showRecentHistories() |
|||
|
|||
case .banks: |
|||
wireframe?.showTablePresenter(with: banks, type: type) |
|||
|
|||
case .autodebit: |
|||
wireframe?.showPaymentMode(with: accounts) |
|||
} |
|||
} |
|||
|
|||
func getRecipientName(account: String, bankCode: String) { |
|||
viewModel?.progress(isShow: true) |
|||
interactor?.getRecipientName(account: account, bankCode: bankCode) |
|||
} |
|||
|
|||
func fetchBalance(type: String, fintechUseNumber: String) { |
|||
viewModel?.progress(isShow: true) |
|||
interactor?.fetchBalance(type: type, fintechUseNumber: fintechUseNumber) |
|||
} |
|||
|
|||
func send(with model: DomesticRemitRequestModel) { |
|||
domesticRequestModel = model |
|||
|
|||
switch model.type.lowercased() { |
|||
case "wallet": |
|||
if let isUseBiometric = KeyChain.shared.get(key: .biometricAuth), isUseBiometric == "1" { |
|||
wireframe?.showBiometricAuth(with: domesticRequestModel) |
|||
} else { |
|||
wireframe?.showSecureKeypad(with: domesticRequestModel) |
|||
} |
|||
default: |
|||
if let isUseBiometric = KeyChain.shared.get(key: .biometricAuth), isUseBiometric == "1" { |
|||
wireframe?.showBiometricAuth(with: domesticRequestModel) |
|||
} else { |
|||
wireframe?.showOTP(with: domesticRequestModel) |
|||
} |
|||
} |
|||
} |
|||
|
|||
func goReceipt(with model: DomesticRemitResponseModel) { |
|||
wireframe?.goReceipt(with: model) |
|||
} |
|||
} |
|||
|
|||
// MARK: DomesticRemit interactor output interface |
|||
extension DomesticRemitPresenter: DomesticRemitInteractorOutput { |
|||
func setModel(with model: DomesticRemitModel) { |
|||
viewModel?.progress(isShow: false) |
|||
|
|||
banks = model.banks |
|||
accounts = model.accounts |
|||
|
|||
viewModel?.setModel(with: model) |
|||
} |
|||
|
|||
func setRecipientName(with model: RecipientNameModel) { |
|||
viewModel?.progress(isShow: false) |
|||
viewModel?.setRecipientName(with: model) |
|||
} |
|||
|
|||
func setBalance(with model: BalanceModel) { |
|||
viewModel?.progress(isShow: false) |
|||
viewModel?.setBalance(with: model) |
|||
} |
|||
|
|||
func setError(with error: Error) { |
|||
viewModel?.progress(isShow: false) |
|||
viewModel?.setError(with: error) |
|||
} |
|||
|
|||
func setSendSuccess(with model: ResponseContainerObject<DomesticRemitResponseModel>) { |
|||
viewModel?.progress(isShow: false) |
|||
viewModel?.successRemit(with: model) |
|||
} |
|||
} |
|||
|
|||
// MARK: DomesticRemit wireframe output interface |
|||
extension DomesticRemitPresenter: DomesticRemitWireframeOutput { |
|||
func selectedData(with model: TablePresenterProtocol?, type: ShowType) { |
|||
viewModel?.selectedData(with: model, type: type) |
|||
} |
|||
|
|||
func setPassword(_ encryptedPW: String) { |
|||
guard var model = domesticRequestModel else { |
|||
let error = NSError(domain: "Remittace", code: 0, message: "Don't set DomesticRequestModel Model") |
|||
viewModel?.setError(with: error) |
|||
return |
|||
} |
|||
|
|||
viewModel?.progress(isShow: true) |
|||
|
|||
model.password = encryptedPW |
|||
interactor?.send(with: model) |
|||
} |
|||
} |
@ -1,48 +0,0 @@ |
|||
// |
|||
// DomesticBankListTableViewCell.swift |
|||
// GME Remit |
|||
// |
|||
// Created by Jeongbae Kong on 2020/03/20. |
|||
// Copyright © 2020 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import UIKit |
|||
|
|||
class DomesticBankListTableViewCell: UITableViewCell { |
|||
|
|||
@IBOutlet private weak var bankNameLabel: UILabel! |
|||
@IBOutlet private weak var checkMarkImageView: UIImageView! |
|||
@IBOutlet private weak var domesticBankListBackgroundView: UIView! |
|||
|
|||
override func awakeFromNib() { |
|||
super.awakeFromNib() |
|||
// Initialization code |
|||
} |
|||
|
|||
func setModel(_ model: Account) { |
|||
|
|||
checkMarkImageView.isHidden = true |
|||
|
|||
if model.type == "wallet" { |
|||
bankNameLabel.text = model.bankName |
|||
} else { |
|||
guard let account = model.accountNumMasked else { |
|||
return bankNameLabel.text = model.bankName |
|||
} |
|||
bankNameLabel.text = "\(model.bankName ?? "") \(account)" |
|||
} |
|||
} |
|||
|
|||
override func setSelected(_ selected: Bool, animated: Bool) { |
|||
super.setSelected(selected, animated: animated) |
|||
if selected { |
|||
domesticBankListBackgroundView.layer.borderWidth = 1 |
|||
domesticBankListBackgroundView.layer.borderColor = UIColor.themeRed.cgColor |
|||
checkMarkImageView.isHidden = false |
|||
|
|||
} else { |
|||
domesticBankListBackgroundView.layer.borderColor = UIColor.clear.cgColor |
|||
checkMarkImageView.isHidden = true |
|||
} |
|||
} |
|||
} |
@ -1,633 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Sd9-9A-f1x"> |
|||
<device id="retina4_7" orientation="portrait" appearance="light"/> |
|||
<dependencies> |
|||
<deployment identifier="iOS"/> |
|||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16086"/> |
|||
<capability name="Named colors" minToolsVersion="9.0"/> |
|||
<capability name="Safe area layout guides" minToolsVersion="9.0"/> |
|||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> |
|||
</dependencies> |
|||
<customFonts key="customFonts"> |
|||
<array key="SanFranciscoDisplay-Bold.otf"> |
|||
<string>SanFranciscoDisplay-Bold</string> |
|||
</array> |
|||
<array key="SanFranciscoDisplay-Medium.otf"> |
|||
<string>SanFranciscoDisplay-Medium</string> |
|||
</array> |
|||
<array key="SanFranciscoDisplay-Regular.otf"> |
|||
<string>SanFranciscoDisplay-Regular</string> |
|||
</array> |
|||
</customFonts> |
|||
<scenes> |
|||
<!--DomesticRemit--> |
|||
<scene sceneID="R60-Pu-Hpy"> |
|||
<objects> |
|||
<viewController storyboardIdentifier="DomesticRemitViewController" title="DomesticRemit" id="HSb-ou-7T5" customClass="DomesticRemitViewController" customModule="GME_Remit" sceneMemberID="viewController"> |
|||
<view key="view" contentMode="scaleToFill" id="9Uc-9s-KgO"> |
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="730"/> |
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> |
|||
<subviews> |
|||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2Ck-HF-rZz"> |
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="730"/> |
|||
<subviews> |
|||
<view contentMode="scaleToFill" placeholderIntrinsicWidth="375" placeholderIntrinsicHeight="575" translatesAutoresizingMaskIntoConstraints="NO" id="att-q4-f6H"> |
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="833"/> |
|||
<subviews> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0TS-Id-072"> |
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="286.5"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="NIp-JO-z9g"> |
|||
<rect key="frame" x="20" y="5" width="335" height="261.5"/> |
|||
<subviews> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Tto-Ts-aSB"> |
|||
<rect key="frame" x="0.0" y="0.0" width="335" height="166"/> |
|||
<subviews> |
|||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="A9a-kE-Ego"> |
|||
<rect key="frame" x="0.0" y="0.0" width="335" height="166"/> |
|||
<color key="backgroundColor" name="ThemeSubBackground"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="166" id="9w6-VG-gnf"/> |
|||
<constraint firstAttribute="width" constant="335" id="SuM-YR-K6X"/> |
|||
</constraints> |
|||
<prototypes> |
|||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="DomesticBankListTableViewCell" rowHeight="121" id="kvD-Ar-usv" customClass="DomesticBankListTableViewCell" customModule="GME_Remit" customModuleProvider="target"> |
|||
<rect key="frame" x="0.0" y="28" width="335" height="121"/> |
|||
<autoresizingMask key="autoresizingMask"/> |
|||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="kvD-Ar-usv" id="hXB-wm-lJm"> |
|||
<rect key="frame" x="0.0" y="0.0" width="335" height="121"/> |
|||
<autoresizingMask key="autoresizingMask"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="iGn-dQ-f23"> |
|||
<rect key="frame" x="25" y="14" width="285" height="93"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="orK-1d-Iaq"> |
|||
<rect key="frame" x="0.0" y="0.0" width="285" height="93"/> |
|||
<subviews> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="PaymentType" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3un-2Z-cuW"> |
|||
<rect key="frame" x="0.0" y="0.0" width="263" height="93"/> |
|||
<gestureRecognizers/> |
|||
<fontDescription key="fontDescription" type="system" pointSize="15"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="right" translatesAutoresizingMaskIntoConstraints="NO" id="tjJ-CO-e1w"> |
|||
<rect key="frame" x="263" y="0.0" width="22" height="93"/> |
|||
<constraints> |
|||
<constraint firstAttribute="width" constant="22" id="y9B-yD-eil"/> |
|||
</constraints> |
|||
</imageView> |
|||
</subviews> |
|||
<gestureRecognizers/> |
|||
</stackView> |
|||
</subviews> |
|||
<gestureRecognizers/> |
|||
</stackView> |
|||
</subviews> |
|||
<constraints> |
|||
<constraint firstAttribute="bottomMargin" secondItem="iGn-dQ-f23" secondAttribute="bottom" constant="3" id="4UM-xu-xdV"/> |
|||
<constraint firstItem="iGn-dQ-f23" firstAttribute="leading" secondItem="hXB-wm-lJm" secondAttribute="leadingMargin" constant="10" id="MC8-WJ-v4a"/> |
|||
<constraint firstItem="iGn-dQ-f23" firstAttribute="top" secondItem="hXB-wm-lJm" secondAttribute="topMargin" constant="3" id="MCd-qc-HN2"/> |
|||
<constraint firstAttribute="trailingMargin" secondItem="iGn-dQ-f23" secondAttribute="trailing" constant="10" id="g2H-eo-WhT"/> |
|||
</constraints> |
|||
</tableViewCellContentView> |
|||
<color key="backgroundColor" name="ThemeSubBackground"/> |
|||
<connections> |
|||
<outlet property="bankNameLabel" destination="3un-2Z-cuW" id="C4U-t9-u02"/> |
|||
<outlet property="checkMarkImageView" destination="tjJ-CO-e1w" id="jR4-5q-abN"/> |
|||
<outlet property="domesticBankListBackgroundView" destination="hXB-wm-lJm" id="3RQ-c6-DME"/> |
|||
</connections> |
|||
</tableViewCell> |
|||
</prototypes> |
|||
</tableView> |
|||
</subviews> |
|||
<color key="backgroundColor" name="ThemeWhite"/> |
|||
<constraints> |
|||
<constraint firstItem="A9a-kE-Ego" firstAttribute="leading" secondItem="Tto-Ts-aSB" secondAttribute="leading" id="1aw-Az-QUp"/> |
|||
<constraint firstItem="A9a-kE-Ego" firstAttribute="top" secondItem="Tto-Ts-aSB" secondAttribute="top" id="F21-j7-8eJ"/> |
|||
<constraint firstAttribute="bottom" secondItem="A9a-kE-Ego" secondAttribute="bottom" id="Vjr-Sh-FXO"/> |
|||
<constraint firstAttribute="trailing" secondItem="A9a-kE-Ego" secondAttribute="trailing" id="mUC-rI-JQk"/> |
|||
</constraints> |
|||
</view> |
|||
<stackView hidden="YES" opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gPj-g8-2ov"> |
|||
<rect key="frame" x="0.0" y="173.5" width="335" height="50"/> |
|||
<subviews> |
|||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="YRe-d3-yhC" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target"> |
|||
<rect key="frame" x="0.0" y="0.0" width="305" height="50"/> |
|||
<color key="tintColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="oXe-1h-5E9"/> |
|||
</constraints> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="17"/> |
|||
<textInputTraits key="textInputTraits"/> |
|||
<userDefinedRuntimeAttributes> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="YES"/> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Select your Auto-debit Account"/> |
|||
</userDefinedRuntimeAttributes> |
|||
</textField> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GVA-E4-iXk"> |
|||
<rect key="frame" x="305" y="0.0" width="30" height="50"/> |
|||
<subviews> |
|||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="lEj-uX-aLI"> |
|||
<rect key="frame" x="0.0" y="14.5" width="30" height="30"/> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="width" constant="30" id="NGc-vF-OmM"/> |
|||
<constraint firstAttribute="height" constant="30" id="ec9-wR-xap"/> |
|||
</constraints> |
|||
</imageView> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<gestureRecognizers/> |
|||
<constraints> |
|||
<constraint firstItem="lEj-uX-aLI" firstAttribute="centerY" secondItem="GVA-E4-iXk" secondAttribute="centerY" multiplier="1:0.85" id="0QP-7R-3Yh"/> |
|||
<constraint firstItem="lEj-uX-aLI" firstAttribute="centerX" secondItem="GVA-E4-iXk" secondAttribute="centerX" id="Piv-FH-osv"/> |
|||
<constraint firstAttribute="width" constant="30" id="c91-Wv-FbA"/> |
|||
</constraints> |
|||
<connections> |
|||
<outletCollection property="gestureRecognizers" destination="JSv-vs-VHU" appends="YES" id="OX6-be-mvG"/> |
|||
</connections> |
|||
</view> |
|||
</subviews> |
|||
</stackView> |
|||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="KCg-go-VB8"> |
|||
<rect key="frame" x="0.0" y="181" width="335" height="80.5"/> |
|||
<subviews> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zVR-3D-DdR"> |
|||
<rect key="frame" x="0.0" y="0.0" width="335" height="0.5"/> |
|||
<color key="backgroundColor" name="ThemeSeparate"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="0.5" id="Bt0-Zo-net"/> |
|||
</constraints> |
|||
</view> |
|||
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="nF9-xv-g3V"> |
|||
<rect key="frame" x="0.0" y="10.5" width="335" height="30"/> |
|||
<subviews> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="253" verticalHuggingPriority="251" text="Available Balance" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SYv-xg-jya"> |
|||
<rect key="frame" x="0.0" y="0.0" width="77.5" height="30"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lpH-nz-meb"> |
|||
<rect key="frame" x="82.5" y="0.0" width="140.5" height="30"/> |
|||
<fontDescription key="fontDescription" type="system" pointSize="17"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<view contentMode="scaleToFill" horizontalHuggingPriority="252" translatesAutoresizingMaskIntoConstraints="NO" id="Zoq-Ph-ipO"> |
|||
<rect key="frame" x="228" y="0.0" width="53" height="30"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pJB-eJ-bWJ"> |
|||
<rect key="frame" x="0.0" y="0.0" width="53" height="30"/> |
|||
<subviews> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" text="N/A" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="crF-eg-HNv"> |
|||
<rect key="frame" x="0.0" y="0.0" width="24" height="30"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="14"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" KRW" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JOx-My-xUB"> |
|||
<rect key="frame" x="24" y="0.0" width="29" height="30"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
</stackView> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="pJB-eJ-bWJ" firstAttribute="leading" secondItem="Zoq-Ph-ipO" secondAttribute="leading" id="8qO-TS-f5h"/> |
|||
<constraint firstItem="pJB-eJ-bWJ" firstAttribute="top" secondItem="Zoq-Ph-ipO" secondAttribute="top" id="9RI-TG-bPS"/> |
|||
<constraint firstAttribute="trailing" secondItem="pJB-eJ-bWJ" secondAttribute="trailing" id="KO6-mI-j0X"/> |
|||
<constraint firstAttribute="bottom" secondItem="pJB-eJ-bWJ" secondAttribute="bottom" id="xRn-NY-zgy"/> |
|||
</constraints> |
|||
</view> |
|||
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="252" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FST-pR-26v"> |
|||
<rect key="frame" x="286" y="0.0" width="49" height="30"/> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="200" id="HFP-Er-dv5"/> |
|||
</constraints> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Bold" family="San Francisco Display" pointSize="14"/> |
|||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="5" maxY="2"/> |
|||
<state key="normal" title="잔액조회"> |
|||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
</state> |
|||
</button> |
|||
</subviews> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="30" id="mRA-WQ-Lmb"/> |
|||
</constraints> |
|||
</stackView> |
|||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="Nbh-pZ-YHM"> |
|||
<rect key="frame" x="0.0" y="50.5" width="335" height="30"/> |
|||
<subviews> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Service Fee" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CmV-2a-OdT"> |
|||
<rect key="frame" x="0.0" y="0.0" width="167.5" height="30"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="1,000 (KRW)" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="y8p-0Z-AAL"> |
|||
<rect key="frame" x="167.5" y="0.0" width="167.5" height="30"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="30" id="k9k-A2-8vR"/> |
|||
</constraints> |
|||
</stackView> |
|||
</subviews> |
|||
</stackView> |
|||
</subviews> |
|||
</stackView> |
|||
</subviews> |
|||
<color key="backgroundColor" name="ThemeSubBackground"/> |
|||
<constraints> |
|||
<constraint firstAttribute="trailing" secondItem="NIp-JO-z9g" secondAttribute="trailing" constant="20" id="49C-sk-Lnv"/> |
|||
<constraint firstAttribute="bottom" secondItem="NIp-JO-z9g" secondAttribute="bottom" constant="20" id="OPa-VP-hxT"/> |
|||
<constraint firstItem="NIp-JO-z9g" firstAttribute="leading" secondItem="0TS-Id-072" secondAttribute="leading" constant="20" id="oz2-GS-lv9"/> |
|||
<constraint firstItem="NIp-JO-z9g" firstAttribute="top" secondItem="0TS-Id-072" secondAttribute="top" constant="5" id="rAH-II-bAa"/> |
|||
</constraints> |
|||
</view> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="me5-tr-dab"> |
|||
<rect key="frame" x="10" y="287" width="355" height="536"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="Rbv-gn-yFV"> |
|||
<rect key="frame" x="10" y="10" width="335" height="516"/> |
|||
<subviews> |
|||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="llz-Zu-HbC" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target"> |
|||
<rect key="frame" x="0.0" y="0.0" width="335" height="50"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="kJe-RG-2Ot"/> |
|||
</constraints> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Bold" family="San Francisco Display" pointSize="19"/> |
|||
<textInputTraits key="textInputTraits" keyboardType="numberPad"/> |
|||
<userDefinedRuntimeAttributes> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="titleText" value="Send Amount (KRW)"/> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Enter send amount (KRW)"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/> |
|||
</userDefinedRuntimeAttributes> |
|||
</textField> |
|||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="wV6-Ic-ufc"> |
|||
<rect key="frame" x="0.0" y="70" width="335" height="446"/> |
|||
<subviews> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="o37-sL-MaJ"> |
|||
<rect key="frame" x="0.0" y="0.0" width="335" height="190"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="TF3-ZE-jcy"> |
|||
<rect key="frame" x="10" y="0.0" width="315" height="190"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eAq-NK-j8L"> |
|||
<rect key="frame" x="0.0" y="0.0" width="315" height="50"/> |
|||
<subviews> |
|||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="12" translatesAutoresizingMaskIntoConstraints="NO" id="w0i-OB-a1z" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target"> |
|||
<rect key="frame" x="0.0" y="0.0" width="245" height="50"/> |
|||
<color key="tintColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="zPm-Kf-gje"/> |
|||
</constraints> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="17"/> |
|||
<textInputTraits key="textInputTraits"/> |
|||
<userDefinedRuntimeAttributes> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="titleText" value="Bank"/> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Select Bank"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="YES"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/> |
|||
<userDefinedRuntimeAttribute type="image" keyPath="leftImage" value="ic_bank"/> |
|||
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor"> |
|||
<color key="value" name="ThemeText"/> |
|||
</userDefinedRuntimeAttribute> |
|||
</userDefinedRuntimeAttributes> |
|||
</textField> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Oci-4B-frb"> |
|||
<rect key="frame" x="245" y="0.0" width="30" height="50"/> |
|||
<subviews> |
|||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="NvU-Xp-kr1"> |
|||
<rect key="frame" x="0.0" y="14.5" width="30" height="30"/> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="width" constant="30" id="MKE-lg-2Vc"/> |
|||
<constraint firstAttribute="height" constant="30" id="VtJ-i1-k2E"/> |
|||
</constraints> |
|||
</imageView> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<gestureRecognizers/> |
|||
<constraints> |
|||
<constraint firstAttribute="width" constant="30" id="GTR-yA-IqE"/> |
|||
<constraint firstItem="NvU-Xp-kr1" firstAttribute="centerX" secondItem="Oci-4B-frb" secondAttribute="centerX" id="jF1-Rd-Pcn"/> |
|||
<constraint firstItem="NvU-Xp-kr1" firstAttribute="centerY" secondItem="Oci-4B-frb" secondAttribute="centerY" multiplier="1:0.85" id="odp-CE-I8u"/> |
|||
</constraints> |
|||
<connections> |
|||
<outletCollection property="gestureRecognizers" destination="UO0-lt-tVC" appends="YES" id="w1J-Uv-aCY"/> |
|||
</connections> |
|||
</view> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nva-Ya-0qv"> |
|||
<rect key="frame" x="275" y="0.0" width="10" height="50"/> |
|||
<constraints> |
|||
<constraint firstAttribute="width" constant="10" id="jsC-vJ-RqV"/> |
|||
</constraints> |
|||
<fontDescription key="fontDescription" type="system" pointSize="17"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Axn-7w-JlA"> |
|||
<rect key="frame" x="285" y="0.0" width="30" height="50"/> |
|||
<subviews> |
|||
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="y20-K6-Nqn"> |
|||
<rect key="frame" x="0.0" y="14.5" width="30" height="30"/> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="width" constant="30" id="OIu-71-u8h"/> |
|||
<constraint firstAttribute="height" constant="30" id="mds-Hy-TsR"/> |
|||
</constraints> |
|||
<color key="tintColor" name="ThemeText"/> |
|||
<inset key="imageEdgeInsets" minX="10" minY="5" maxX="5" maxY="5"/> |
|||
<state key="normal" image="ic_review"/> |
|||
</button> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<gestureRecognizers/> |
|||
<constraints> |
|||
<constraint firstItem="y20-K6-Nqn" firstAttribute="centerX" secondItem="Axn-7w-JlA" secondAttribute="centerX" id="3uX-bp-kjq"/> |
|||
<constraint firstAttribute="width" constant="30" id="BLk-Ld-m1H"/> |
|||
<constraint firstItem="y20-K6-Nqn" firstAttribute="centerY" secondItem="Axn-7w-JlA" secondAttribute="centerY" multiplier="1:0.85" id="Sz9-yp-8Cs"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
</stackView> |
|||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="HP6-ed-Nsb" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target"> |
|||
<rect key="frame" x="0.0" y="70" width="315" height="50"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="Rda-Uz-UNf"/> |
|||
</constraints> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="17"/> |
|||
<textInputTraits key="textInputTraits" keyboardType="numberPad"/> |
|||
<userDefinedRuntimeAttributes> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="titleText" value="Account Number"/> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Enter account number"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="YES"/> |
|||
</userDefinedRuntimeAttributes> |
|||
</textField> |
|||
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ARJ-wR-Qth"> |
|||
<rect key="frame" x="0.0" y="140" width="315" height="50"/> |
|||
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="Lj3-hr-AGQ"/> |
|||
</constraints> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="17"/> |
|||
<state key="normal" title="Ok"> |
|||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
</state> |
|||
</button> |
|||
</subviews> |
|||
</stackView> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="TF3-ZE-jcy" firstAttribute="top" secondItem="o37-sL-MaJ" secondAttribute="top" id="J6O-mL-owU"/> |
|||
<constraint firstAttribute="trailing" secondItem="TF3-ZE-jcy" secondAttribute="trailing" constant="10" id="S2Y-JQ-Tie"/> |
|||
<constraint firstAttribute="bottom" secondItem="TF3-ZE-jcy" secondAttribute="bottom" id="Zq1-eF-dDO"/> |
|||
<constraint firstItem="TF3-ZE-jcy" firstAttribute="leading" secondItem="o37-sL-MaJ" secondAttribute="leading" constant="10" id="pkd-6p-S8T"/> |
|||
</constraints> |
|||
</view> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sDV-rn-swX"> |
|||
<rect key="frame" x="0.0" y="210" width="335" height="236"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="4tZ-8j-Zm2"> |
|||
<rect key="frame" x="10" y="0.0" width="315" height="236"/> |
|||
<subviews> |
|||
<textField opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Zv6-JS-Obe" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target"> |
|||
<rect key="frame" x="0.0" y="0.0" width="315" height="50"/> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="9Vo-Te-ee3"/> |
|||
</constraints> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="17"/> |
|||
<textInputTraits key="textInputTraits"/> |
|||
<userDefinedRuntimeAttributes> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="titleText" value="Recipient's Name"/> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Recipient's Name"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="YES"/> |
|||
</userDefinedRuntimeAttributes> |
|||
</textField> |
|||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Enter recipient's phone number" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="xHy-UE-MgN" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target"> |
|||
<rect key="frame" x="0.0" y="65" width="315" height="50"/> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="Ea4-uA-N7E"/> |
|||
</constraints> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="17"/> |
|||
<textInputTraits key="textInputTraits" keyboardType="phonePad"/> |
|||
<userDefinedRuntimeAttributes> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="titleText" value="Recipient's Mobile Number"/> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Enter mobile number (Optional)"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="YES"/> |
|||
</userDefinedRuntimeAttributes> |
|||
</textField> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IDY-N7-kiw"> |
|||
<rect key="frame" x="0.0" y="130" width="315" height="106"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="XlD-OK-DmW"> |
|||
<rect key="frame" x="0.0" y="20" width="315" height="16"/> |
|||
<subviews> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="253" verticalHuggingPriority="251" text="●" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PQ8-Xe-tzc"> |
|||
<rect key="frame" x="0.0" y="0.0" width="8.5" height="16"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="13"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" text="It will deduct oooKRW (Amount + ServiceFee)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="0rB-T2-pd1"> |
|||
<rect key="frame" x="13.5" y="0.0" width="301.5" height="16"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="13"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
</stackView> |
|||
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="UYi-o5-Inc"> |
|||
<rect key="frame" x="-20" y="56" width="355" height="50"/> |
|||
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="Cft-tW-Ta2"/> |
|||
</constraints> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="17"/> |
|||
<inset key="imageEdgeInsets" minX="-20" minY="0.0" maxX="0.0" maxY="0.0"/> |
|||
<state key="normal" title="Send Money" image="ic_ExSend"> |
|||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
</state> |
|||
</button> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="XlD-OK-DmW" firstAttribute="top" secondItem="IDY-N7-kiw" secondAttribute="top" constant="20" id="1fI-2M-taq"/> |
|||
<constraint firstItem="XlD-OK-DmW" firstAttribute="leading" secondItem="IDY-N7-kiw" secondAttribute="leading" id="LJq-ea-lIA"/> |
|||
<constraint firstItem="UYi-o5-Inc" firstAttribute="top" secondItem="XlD-OK-DmW" secondAttribute="bottom" constant="20" id="YMP-dd-VKP"/> |
|||
<constraint firstAttribute="trailing" secondItem="UYi-o5-Inc" secondAttribute="trailing" constant="-20" id="cWD-mv-XBN"/> |
|||
<constraint firstAttribute="bottom" secondItem="UYi-o5-Inc" secondAttribute="bottom" id="jal-cN-33V"/> |
|||
<constraint firstAttribute="trailing" secondItem="XlD-OK-DmW" secondAttribute="trailing" id="rXV-vI-4RS"/> |
|||
<constraint firstItem="UYi-o5-Inc" firstAttribute="leading" secondItem="IDY-N7-kiw" secondAttribute="leading" constant="-20" id="vxm-Wh-cuw"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
</stackView> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="trailing" secondItem="4tZ-8j-Zm2" secondAttribute="trailing" constant="10" id="0SY-4j-vCE"/> |
|||
<constraint firstItem="4tZ-8j-Zm2" firstAttribute="top" secondItem="sDV-rn-swX" secondAttribute="top" id="DpA-IS-HGd"/> |
|||
<constraint firstItem="4tZ-8j-Zm2" firstAttribute="leading" secondItem="sDV-rn-swX" secondAttribute="leading" constant="10" id="NUI-pO-Ccy"/> |
|||
<constraint firstAttribute="bottom" secondItem="4tZ-8j-Zm2" secondAttribute="bottom" id="ebH-gv-hze"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
</stackView> |
|||
</subviews> |
|||
</stackView> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="Rbv-gn-yFV" firstAttribute="leading" secondItem="me5-tr-dab" secondAttribute="leading" constant="10" id="224-hO-IeM"/> |
|||
<constraint firstItem="Rbv-gn-yFV" firstAttribute="top" secondItem="me5-tr-dab" secondAttribute="top" constant="10" id="5hl-Ov-Kz9"/> |
|||
<constraint firstAttribute="trailing" secondItem="Rbv-gn-yFV" secondAttribute="trailing" constant="10" id="VbY-HO-wiP"/> |
|||
<constraint firstAttribute="bottom" secondItem="Rbv-gn-yFV" secondAttribute="bottom" constant="10" id="cXA-HM-n2R"/> |
|||
</constraints> |
|||
</view> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HNr-Vg-UtG"> |
|||
<rect key="frame" x="0.0" y="286.5" width="375" height="0.5"/> |
|||
<color key="backgroundColor" name="ThemeSeparate"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="0.5" id="en2-Cw-FD0"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="me5-tr-dab" firstAttribute="top" secondItem="HNr-Vg-UtG" secondAttribute="bottom" id="AHz-Pz-98M"/> |
|||
<constraint firstItem="HNr-Vg-UtG" firstAttribute="top" secondItem="0TS-Id-072" secondAttribute="bottom" id="Gjn-6h-LdM"/> |
|||
<constraint firstItem="HNr-Vg-UtG" firstAttribute="leading" secondItem="att-q4-f6H" secondAttribute="leading" id="LUb-N2-lef"/> |
|||
<constraint firstAttribute="trailing" secondItem="me5-tr-dab" secondAttribute="trailing" constant="10" id="LaW-qS-mZ8"/> |
|||
<constraint firstItem="0TS-Id-072" firstAttribute="leading" secondItem="att-q4-f6H" secondAttribute="leading" id="Lk5-Y5-XGQ"/> |
|||
<constraint firstItem="0TS-Id-072" firstAttribute="top" secondItem="att-q4-f6H" secondAttribute="top" id="k48-n6-USF"/> |
|||
<constraint firstAttribute="bottom" secondItem="me5-tr-dab" secondAttribute="bottom" constant="10" id="kzi-EQ-EQp"/> |
|||
<constraint firstItem="me5-tr-dab" firstAttribute="leading" secondItem="att-q4-f6H" secondAttribute="leading" constant="10" id="lzA-66-lwH"/> |
|||
<constraint firstAttribute="trailing" secondItem="HNr-Vg-UtG" secondAttribute="trailing" id="wJG-uY-G5r"/> |
|||
<constraint firstAttribute="trailing" secondItem="0TS-Id-072" secondAttribute="trailing" id="zvh-Jz-Qmt"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
<constraints> |
|||
<constraint firstAttribute="trailing" secondItem="att-q4-f6H" secondAttribute="trailing" id="NLc-4P-6iE"/> |
|||
<constraint firstItem="att-q4-f6H" firstAttribute="leading" secondItem="2Ck-HF-rZz" secondAttribute="leading" id="Uad-Wi-K4y"/> |
|||
<constraint firstItem="att-q4-f6H" firstAttribute="width" secondItem="2Ck-HF-rZz" secondAttribute="width" id="deG-TI-x5e"/> |
|||
<constraint firstItem="att-q4-f6H" firstAttribute="top" secondItem="2Ck-HF-rZz" secondAttribute="top" id="exA-kP-hrn"/> |
|||
<constraint firstAttribute="bottom" secondItem="att-q4-f6H" secondAttribute="bottom" id="oBi-Y2-98u"/> |
|||
</constraints> |
|||
</scrollView> |
|||
</subviews> |
|||
<color key="backgroundColor" name="ThemeMainBackground"/> |
|||
<constraints> |
|||
<constraint firstAttribute="trailing" secondItem="2Ck-HF-rZz" secondAttribute="trailing" id="1Oi-8m-DES"/> |
|||
<constraint firstItem="2Ck-HF-rZz" firstAttribute="leading" secondItem="9Uc-9s-KgO" secondAttribute="leading" id="3T0-Z4-Rbv"/> |
|||
<constraint firstItem="2Ck-HF-rZz" firstAttribute="top" secondItem="9Uc-9s-KgO" secondAttribute="top" id="SV6-Xz-azw"/> |
|||
<constraint firstItem="O1T-1R-Sun" firstAttribute="bottom" secondItem="2Ck-HF-rZz" secondAttribute="bottom" id="foV-kH-Tqo"/> |
|||
</constraints> |
|||
<viewLayoutGuide key="safeArea" id="O1T-1R-Sun"/> |
|||
</view> |
|||
<navigationItem key="navigationItem" title="Local Transfer" id="Osp-Sl-e7G"/> |
|||
<size key="freeformSize" width="375" height="730"/> |
|||
<connections> |
|||
<outlet property="accountTextField" destination="HP6-ed-Nsb" id="pJc-Uh-WXE"/> |
|||
<outlet property="amountTextField" destination="llz-Zu-HbC" id="fTk-6G-fRa"/> |
|||
<outlet property="autoDebitTextField" destination="YRe-d3-yhC" id="soQ-vQ-EVY"/> |
|||
<outlet property="autodebitAccountDropDownImageView" destination="lEj-uX-aLI" id="nB2-Xh-tkR"/> |
|||
<outlet property="autodebitDropDownTap" destination="JSv-vs-VHU" id="hKR-ip-2GN"/> |
|||
<outlet property="balaceTitleLabel" destination="SYv-xg-jya" id="Ia2-mk-dgJ"/> |
|||
<outlet property="balanceButton" destination="FST-pR-26v" id="fjO-x9-VAl"/> |
|||
<outlet property="balanceContainerView" destination="Zoq-Ph-ipO" id="rKz-0n-eYw"/> |
|||
<outlet property="balanceLabel" destination="crF-eg-HNv" id="u6O-Xb-WhA"/> |
|||
<outlet property="balanceMainContainerView" destination="KCg-go-VB8" id="Uly-UD-vj2"/> |
|||
<outlet property="bankDropDownImageView" destination="NvU-Xp-kr1" id="nDy-FO-68U"/> |
|||
<outlet property="bankDropDownTap" destination="UO0-lt-tVC" id="XXd-zY-ad4"/> |
|||
<outlet property="bankTextField" destination="w0i-OB-a1z" id="yaB-N4-zrt"/> |
|||
<outlet property="descriptionLabel" destination="0rB-T2-pd1" id="cJy-Np-IHy"/> |
|||
<outlet property="detailContainerView" destination="wV6-Ic-ufc" id="00v-E7-OYr"/> |
|||
<outlet property="getNameButton" destination="ARJ-wR-Qth" id="5Xg-8m-m3F"/> |
|||
<outlet property="mainContainerView" destination="me5-tr-dab" id="Xvk-d6-het"/> |
|||
<outlet property="mobileTextField" destination="xHy-UE-MgN" id="bpR-fu-S50"/> |
|||
<outlet property="recentHistoryButton" destination="y20-K6-Nqn" id="pU0-Zv-V4g"/> |
|||
<outlet property="recipientInContainerView" destination="sDV-rn-swX" id="wQh-gV-atm"/> |
|||
<outlet property="recipientNameTextField" destination="Zv6-JS-Obe" id="ia0-2V-981"/> |
|||
<outlet property="scrollView" destination="2Ck-HF-rZz" id="O7T-2X-csL"/> |
|||
<outlet property="sendButton" destination="UYi-o5-Inc" id="OAE-Q6-Otp"/> |
|||
<outlet property="serviceFeeLabel" destination="y8p-0Z-AAL" id="irY-KD-4K9"/> |
|||
<outlet property="serviceFeeTitleLabel" destination="CmV-2a-OdT" id="Xzm-ae-g7B"/> |
|||
<outlet property="tableView" destination="A9a-kE-Ego" id="8Fw-fr-1ca"/> |
|||
</connections> |
|||
</viewController> |
|||
<placeholder placeholderIdentifier="IBFirstResponder" id="8je-5K-XuW" userLabel="First Responder" sceneMemberID="firstResponder"/> |
|||
<tapGestureRecognizer id="UO0-lt-tVC"/> |
|||
<tapGestureRecognizer id="JSv-vs-VHU"/> |
|||
</objects> |
|||
<point key="canvasLocation" x="847.20000000000005" y="232.08395802098951"/> |
|||
</scene> |
|||
<!--Navigation Controller--> |
|||
<scene sceneID="Km1-NF-cGq"> |
|||
<objects> |
|||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="Sd9-9A-f1x" sceneMemberID="viewController"> |
|||
<toolbarItems/> |
|||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="bin-Cc-0sW"> |
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/> |
|||
<autoresizingMask key="autoresizingMask"/> |
|||
</navigationBar> |
|||
<nil name="viewControllers"/> |
|||
<connections> |
|||
<segue destination="HSb-ou-7T5" kind="relationship" relationship="rootViewController" id="MNO-NP-Kpk"/> |
|||
</connections> |
|||
</navigationController> |
|||
<placeholder placeholderIdentifier="IBFirstResponder" id="gNl-7O-RMX" userLabel="First Responder" sceneMemberID="firstResponder"/> |
|||
</objects> |
|||
<point key="canvasLocation" x="-92" y="232.53373313343329"/> |
|||
</scene> |
|||
</scenes> |
|||
<color key="tintColor" red="0.78177064659999995" green="0.55228364470000002" blue="0.018981300289999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> |
|||
<resources> |
|||
<image name="ic_ExSend" width="20" height="19"/> |
|||
<image name="ic_bank" width="51" height="51"/> |
|||
<image name="ic_review" width="28" height="39"/> |
|||
<image name="right" width="22" height="22"/> |
|||
<namedColor name="ThemeMainBackground"> |
|||
<color red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> |
|||
</namedColor> |
|||
<namedColor name="ThemeSeparate"> |
|||
<color red="0.82400000095367432" green="0.82400000095367432" blue="0.82400000095367432" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> |
|||
</namedColor> |
|||
<namedColor name="ThemeSubBackground"> |
|||
<color red="0.93300002813339233" green="0.93300002813339233" blue="0.93300002813339233" alpha="1" colorSpace="custom" customColorSpace="displayP3"/> |
|||
</namedColor> |
|||
<namedColor name="ThemeText"> |
|||
<color red="0.28999999165534973" green="0.28999999165534973" blue="0.28999999165534973" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> |
|||
</namedColor> |
|||
<namedColor name="ThemeWhite"> |
|||
<color red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> |
|||
</namedColor> |
|||
</resources> |
|||
</document> |
@ -1,490 +0,0 @@ |
|||
// |
|||
// DomesticRemitViewController.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import UIKit |
|||
import RxSwift |
|||
import RxCocoa |
|||
|
|||
class DomesticRemitViewController: UIViewController { |
|||
|
|||
// MARK: Properties |
|||
var viewModel: DomesticRemitViewModel! |
|||
var bankModel: [Account]? |
|||
|
|||
private let disposeBag = DisposeBag() |
|||
// MARK: Computed Properties |
|||
|
|||
// MARK: IBOutlets |
|||
@IBOutlet private weak var mainContainerView: UIView! |
|||
@IBOutlet private weak var amountTextField: ValidationTextField! |
|||
@IBOutlet private weak var recentHistoryButton: UIButton! |
|||
|
|||
@IBOutlet private weak var bankTextField: ValidationTextField! |
|||
@IBOutlet private weak var accountTextField: ValidationTextField! |
|||
@IBOutlet private weak var recipientNameTextField: ValidationTextField! |
|||
@IBOutlet private weak var mobileTextField: ValidationTextField! |
|||
@IBOutlet private weak var autoDebitTextField: ValidationTextField! |
|||
|
|||
@IBOutlet private weak var serviceFeeLabel: UILabel! |
|||
|
|||
@IBOutlet private weak var recipientInContainerView: UIView! |
|||
@IBOutlet private weak var detailContainerView: UIStackView! |
|||
|
|||
@IBOutlet private weak var getNameButton: UIButton! |
|||
@IBOutlet private weak var sendButton: UIButton! |
|||
|
|||
@IBOutlet private weak var balanceButton: UIButton! |
|||
@IBOutlet private weak var balanceLabel: UILabel! |
|||
@IBOutlet private weak var balaceTitleLabel: UILabel! |
|||
@IBOutlet private weak var serviceFeeTitleLabel: UILabel! |
|||
@IBOutlet private weak var balanceMainContainerView: UIStackView! |
|||
|
|||
@IBOutlet weak var tableView: UITableView! |
|||
@IBOutlet private weak var autodebitAccountDropDownImageView: UIImageView! |
|||
@IBOutlet private weak var balanceContainerView: UIView! |
|||
@IBOutlet private weak var bankDropDownImageView: UIImageView! |
|||
@IBOutlet private var bankDropDownTap: UITapGestureRecognizer! |
|||
@IBOutlet private var autodebitDropDownTap: UITapGestureRecognizer! |
|||
|
|||
@IBOutlet private weak var descriptionLabel: UILabel! |
|||
@IBOutlet weak var scrollView: UIScrollView! |
|||
// MARK: VC's Life cycle |
|||
override func viewDidLoad() { |
|||
super.viewDidLoad() |
|||
setup() |
|||
} |
|||
|
|||
override func viewDidAppear(_ animated: Bool) { |
|||
super.viewDidAppear(animated) |
|||
title = "local_transfer_text".localized() |
|||
|
|||
let selectedModel = bankModel?.first(where: {$0.type == "wallet"}) |
|||
if selectedModel != nil { |
|||
let indexPath = IndexPath(row: 0, section: 0) |
|||
self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .top) |
|||
} |
|||
} |
|||
|
|||
override func viewWillDisappear(_ animated: Bool) { |
|||
super.viewWillDisappear(animated) |
|||
title = "" |
|||
view.endEditing(true) |
|||
} |
|||
// MARK: IBActions |
|||
|
|||
} |
|||
|
|||
// MARK: Other Functions |
|||
extension DomesticRemitViewController { |
|||
private func setup() { |
|||
// all setup should be done here |
|||
setBinding() |
|||
|
|||
setMultilanguages() |
|||
setUI() |
|||
|
|||
setupNormalNavigation() |
|||
} |
|||
|
|||
private func setUI() { |
|||
mainContainerView.isHidden = true |
|||
// balanceMainContainerView.isHidden = true |
|||
balanceContainerView.isHidden = true |
|||
balanceButton.isHidden = true |
|||
detailContainerView.isHidden = true |
|||
recipientInContainerView.isHidden = true |
|||
|
|||
sendButton.layer.cornerRadius = 5 |
|||
getNameButton.layer.cornerRadius = 5 |
|||
recentHistoryButton.layer.cornerRadius = 5 |
|||
balanceButton.layer.cornerRadius = 5 |
|||
|
|||
// balanceButton.layer.borderColor = UIColor.themeBlue.cgColor |
|||
// balanceButton.layer.borderWidth = 1 |
|||
balanceButton.backgroundColor = .themeBlue |
|||
balanceButton.setTitleColor(.white, for: .normal) |
|||
balanceButton.titleLabel?.minimumScaleFactor = 0.1 |
|||
balanceButton.titleLabel?.adjustsFontSizeToFitWidth = true |
|||
|
|||
bankDropDownImageView.setDropDownImage(tintColor: .themeTextColor) |
|||
autodebitAccountDropDownImageView.setDropDownImage(tintColor: .themeTextColor) |
|||
|
|||
recipientNameTextField.validCondition = {!$0.isEmpty} |
|||
recipientNameTextField.errorMessage = nil |
|||
|
|||
bankTextField.inputView = UIView() |
|||
bankTextField.keyboardToolbar.isHidden = true |
|||
bankTextField.validCondition = {!$0.isEmpty} |
|||
bankTextField.errorMessage = nil |
|||
|
|||
autoDebitTextField.inputView = UIView() |
|||
autoDebitTextField.keyboardToolbar.isHidden = true |
|||
autoDebitTextField.validCondition = {!$0.isEmpty} |
|||
autoDebitTextField.errorMessage = nil |
|||
|
|||
accountTextField.validCondition = {!$0.isEmpty && $0.count > 8} |
|||
accountTextField.errorMessage = "min_length_account_error_text".localized() |
|||
|
|||
} |
|||
|
|||
private func setMultilanguages() { |
|||
autoDebitTextField.placeholder = "select_auto_debit_account_text".localized() |
|||
balaceTitleLabel.text = "domestic_available_balance_text".localized() |
|||
serviceFeeTitleLabel.text = "transfer_charge_text".localized() |
|||
amountTextField.placeholder = "enter_send_amount_text".localized() |
|||
bankTextField.placeholder = "select_korea_bank".localized() |
|||
accountTextField.placeholder = "enter_account_text".localized() |
|||
accountTextField.titleText = "account_number_text".localized() |
|||
recipientNameTextField.titleText = "recipient_name_text".localized() |
|||
mobileTextField.titleText = "mobile_optional_text".localized() |
|||
mobileTextField.placeholder = "enter_mobile_optional_text".localized() |
|||
|
|||
sendButton.setTitle("send_money_text".localized(), for: .normal) |
|||
balanceButton.setTitle("account_balance_button_text".localized(), for: .normal) |
|||
getNameButton.setTitle("continue_text".localized(), for: .normal) |
|||
} |
|||
|
|||
private func setBinding() { |
|||
let viewWillAppear = rx.sentMessage(#selector(UIViewController.viewWillAppear(_:))) |
|||
.mapToVoid() |
|||
.asDriverOnErrorJustComplete() |
|||
|
|||
let input = DomesticRemitViewModel.Input( |
|||
viewWillAppear: viewWillAppear, |
|||
showBalanceTrigger: balanceButton.rx.tap.asDriver(), |
|||
showRecentHistoryTrigger: recentHistoryButton.rx.tap.asDriver(), |
|||
selectedBankIndex: tableView.rx.itemSelected.map( { $0.row }).asDriverOnErrorJustComplete(), |
|||
selectAutodebit: autoDebitTextField.rx.controlEvent(.editingDidBegin).asDriver(), |
|||
selectBankTrigger: bankTextField.rx.controlEvent(.editingDidBegin).asDriver(), |
|||
amount: amountTextField.rx.text.orEmpty.asDriver(), |
|||
account: accountTextField.rx.text.orEmpty.asDriver(), |
|||
isValidAccount: accountTextField.valid.asDriver(onErrorJustReturn: false), |
|||
mobile: mobileTextField.rx.text.orEmpty.asDriver(), |
|||
getRecipientNameTrigger: getNameButton.rx.tap.asDriver(), |
|||
sendTrigger: sendButton.rx.tap.asDriver() |
|||
) |
|||
|
|||
let output = viewModel.transform(input: input) |
|||
|
|||
// output |
|||
output.isError |
|||
.drive( |
|||
onNext: { self.alert(type: .error, message: $0.localizedDescription) } |
|||
).disposed(by: disposeBag) |
|||
|
|||
output.isProgress |
|||
.drive( |
|||
onNext: { $0 ? self.showProgressHud() : self.hideProgressHud() } |
|||
).disposed(by: disposeBag) |
|||
|
|||
output.getInitialData |
|||
.drive(onNext: { |
|||
if $0?.accounts?.count == 0 { |
|||
self.alertWithOk( |
|||
type: .error, |
|||
message: "doesnt_have_auto_debit_text".localized(), |
|||
okTitle: "ok_text".localized(), |
|||
okAction: { |
|||
self.navigationController?.popViewController(animated: true) |
|||
} |
|||
) |
|||
} |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.selectedServiceFee |
|||
.map { "\($0?.likeCommaMoney() ?? "") KRW" } |
|||
.drive(serviceFeeLabel.rx.text) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.getBalance.map {$0?.balance?.decimalToCurrency()} |
|||
.drive(onNext: { |
|||
guard let balance = $0 else { return } |
|||
self.balanceLabel.text = balance |
|||
self.balanceButton.isHidden = true |
|||
self.amountTextField.becomeFirstResponder() |
|||
|
|||
self.balanceContainerView.animateHidden(isHidden: false) |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.selectedAutodebit |
|||
.drive(onNext: { |
|||
guard |
|||
let model = $0 else { |
|||
self.autoDebitTextField.text = "" |
|||
return |
|||
} |
|||
|
|||
|
|||
|
|||
if model.type == "wallet" { |
|||
self.balanceButton.isHidden = true |
|||
self.balanceLabel.text = GMEDB.shared.user.string(.availableBalance) |
|||
self.balanceContainerView.animateHidden(isHidden: false) |
|||
} else { |
|||
self.balanceButton.isHidden = false |
|||
self.balanceLabel.text = "" |
|||
self.balanceContainerView.animateHidden(isHidden: true) |
|||
} |
|||
|
|||
self.mainContainerView.animateHidden(isHidden: false, duration: 0.2) { |
|||
self.amountTextField.becomeFirstResponder() |
|||
} |
|||
|
|||
guard let account = model.accountNumMasked else { |
|||
self.autoDebitTextField.text = "\(model.bankName ?? "")" |
|||
return |
|||
} |
|||
|
|||
self.autoDebitTextField.text = "\(model.bankName ?? "") (\(account))" |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output |
|||
.fetchBankList.drive(onNext: { [weak self] in |
|||
self?.bankModel = $0 |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output |
|||
.fetchBankList.drive( |
|||
tableView.rx.items(cellIdentifier: "DomesticBankListTableViewCell") |
|||
) { (_, element: Account, cell: DomesticBankListTableViewCell) in |
|||
cell.setModel(element) |
|||
} |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.isAvailableRemit |
|||
.drive(onNext: { isAvailable in |
|||
self.amountTextField.validCondition = {_ in return isAvailable } |
|||
self.amountTextField.valid.onNext(isAvailable) |
|||
|
|||
guard |
|||
let amountText = self.amountTextField.text?.extract(regex: "[0-9]"), |
|||
let amount = Int(amountText) else { return } |
|||
|
|||
let biggerError = "amount_bigger_error_text".localized() |
|||
let minimumError = "amount_minimum_error_text".localized() |
|||
|
|||
if isAvailable == false && amount > 6500000 { |
|||
self.amountTextField.errorMessage = "amount_max_error_text".localized() |
|||
} else { |
|||
self.amountTextField.errorMessage = |
|||
amount > 9999 ? biggerError : minimumError |
|||
} |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.selectedBank |
|||
.drive(onNext: { |
|||
self.recipientInContainerView.animateHidden(isHidden: true) |
|||
|
|||
self.bankTextField.text = $0?.bankName |
|||
self.bankTextField.setBank(with: $0?.bankCode) |
|||
self.bankTextField.sendActions(for: .editingChanged) |
|||
|
|||
self.recipientNameTextField.text = "" |
|||
self.recipientNameTextField.sendActions(for: .editingChanged) |
|||
|
|||
self.mobileTextField.text = "" |
|||
self.mobileTextField.sendActions(for: .editingChanged) |
|||
|
|||
self.getNameButton.isHidden = false |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.selectedRecipient |
|||
.drive(onNext: { |
|||
self.accountTextField.text = $0?.account |
|||
|
|||
if self.bankTextField.text != "" { |
|||
self.accountTextField.sendActions(for: .editingChanged) |
|||
} |
|||
|
|||
self.getNameButton.isHidden = false |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.getRecipientName |
|||
.drive(onNext: { |
|||
guard let model = $0 else { return } |
|||
let message = "check_recipient_name_text".localized() |
|||
.replacingOccurrences(of: "\"ooo\"", with: "") |
|||
|
|||
self.alertWithOkCancel( |
|||
type: .normal, |
|||
message: message, |
|||
title: "\(model.name ?? "nil")", |
|||
okTitle: "confirm_text".localized(), |
|||
cancelTitle: "cancel_text".localized(), |
|||
okAction: { |
|||
self.view.endEditing(true) |
|||
|
|||
self.getNameButton.isHidden = true |
|||
|
|||
self.recipientNameTextField.text = model.name |
|||
self.recipientNameTextField.sendActions(for: .editingChanged) |
|||
|
|||
self.mobileTextField.text = model.mobile |
|||
self.mobileTextField.sendActions(for: .editingChanged) |
|||
|
|||
if model.name != "" { |
|||
self.recipientInContainerView.animateHidden(isHidden: false, duration: 0.3) { |
|||
self.scrollView.toBottom() |
|||
} |
|||
} else { |
|||
self.recipientInContainerView.animateHidden(isHidden: true) |
|||
} |
|||
}, |
|||
cancelAction: {self.getNameButton.isHidden = false} |
|||
) |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.getRecipientName |
|||
.map {$0?.mobile} |
|||
.drive(mobileTextField.rx.text) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.successRemit |
|||
.drive(onNext: { model in |
|||
let message = model.message ?? "" |
|||
guard let data = model.data else {return} |
|||
|
|||
self.alertWithOk( |
|||
type: .success, |
|||
message: message, |
|||
title: "transfer_success_text".localized(), |
|||
okTitle: "ok_text".localized(), |
|||
okAction: { |
|||
output.receiptTrigger.onNext(data) |
|||
}) |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
// amount |
|||
amountTextField.rx.controlEvent(.editingChanged) |
|||
.asDriver() |
|||
.drive(onNext: { |
|||
guard let text = self.amountTextField.text else { return } |
|||
self.amountTextField.text = Utility.getCommaSeperatedString(numberString: text) |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
amountTextField.rx.controlEvent(.editingDidBegin) |
|||
.asDriver() |
|||
.drive(onNext: { |
|||
self.amountTextField.text = self.amountTextField.text?.replacingOccurrences( |
|||
of: " KRW", with: "" |
|||
) |
|||
self.detailContainerView.animateHidden(isHidden: true) |
|||
}).disposed(by: disposeBag) |
|||
|
|||
amountTextField.rx.controlEvent(.editingDidEnd) |
|||
.asDriver() |
|||
.withLatestFrom(output.isAvailableRemit) { $1 } |
|||
.drive(onNext: { |
|||
guard let amount = self.amountTextField.text else { |
|||
return |
|||
} |
|||
|
|||
if amount != "" && $0 { |
|||
self.amountTextField.text = amount + " KRW" |
|||
self.detailContainerView.animateHidden(isHidden: false) |
|||
} |
|||
|
|||
}).disposed(by: disposeBag) |
|||
|
|||
bankDropDownTap.rx.event.mapToVoid().asDriverOnErrorJustComplete() |
|||
.drive(onNext: { |
|||
self.bankTextField.becomeFirstResponder() |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
autodebitDropDownTap.rx.event.mapToVoid().asDriverOnErrorJustComplete() |
|||
.drive(onNext: { |
|||
self.autoDebitTextField.becomeFirstResponder() |
|||
}).disposed(by: disposeBag) |
|||
|
|||
// auto-debit |
|||
autoDebitTextField.rx.controlEvent(.editingDidBegin) |
|||
.asDriver() |
|||
.drive(onNext: { |
|||
self.mainContainerView.animateHidden(isHidden: true) |
|||
}).disposed(by: disposeBag) |
|||
|
|||
// account |
|||
accountTextField.rx.controlEvent(.editingDidBegin) |
|||
.asDriver() |
|||
.drive(onNext: { |
|||
self.recipientNameTextField.text = "" |
|||
self.recipientNameTextField.sendActions(for: .editingChanged) |
|||
self.mobileTextField.text = "" |
|||
self.mobileTextField.sendActions(for: .editingChanged) |
|||
|
|||
self.getNameButton.isHidden = false |
|||
self.recipientInContainerView.animateHidden(isHidden: true) |
|||
self.accountTextField.isLineHidden = false |
|||
}).disposed(by: disposeBag) |
|||
|
|||
accountTextField.rx.controlEvent(.editingDidEnd) |
|||
.asDriver() |
|||
.drive(onNext: { |
|||
self.accountTextField.isLineHidden = true |
|||
}).disposed(by: disposeBag) |
|||
|
|||
// mobile |
|||
mobileTextField.rx.controlEvent(.editingDidBegin) |
|||
.asDriver() |
|||
.drive(onNext: { |
|||
self.mobileTextField.isLineHidden = false |
|||
}).disposed(by: disposeBag) |
|||
|
|||
mobileTextField.rx.controlEvent(.editingDidEnd) |
|||
.asDriver() |
|||
.drive(onNext: { |
|||
self.mobileTextField.isLineHidden = true |
|||
}).disposed(by: disposeBag) |
|||
|
|||
let actualAmount = Observable.combineLatest( |
|||
amountTextField.rx.text.orEmpty.map {Int($0.extract(regex: "[0-9]")) ?? 0}, |
|||
output.selectedServiceFee.asObservable().map {Int($0 ?? "") ?? 0} |
|||
).map {$0 + $1} |
|||
|
|||
// send button |
|||
Observable.combineLatest([accountTextField.valid, recipientNameTextField.valid]) |
|||
.flatMap { Observable.just($0.allSatisfy {$0}) } |
|||
.bind { [weak self] in guard let `self` = self else { return } |
|||
self.sendButton.isHidden = !$0 |
|||
self.sendButton.isEnabled = $0 |
|||
self.sendButton.backgroundColor = $0 ? .themeRed : .lightGray |
|||
// self.sendButton.setTitle(self.amountTextField.text ?? "0 KRW", for: .normal) |
|||
}.disposed(by: disposeBag) |
|||
|
|||
actualAmount.asDriverOnErrorJustComplete() |
|||
.map { |
|||
"will_deduct_info_text".localized() |
|||
.replacingOccurrences(of: "ooo", with: "\("\($0)".decimalToCurrency())") |
|||
} |
|||
.drive(descriptionLabel.rx.text) |
|||
.disposed(by: disposeBag) |
|||
|
|||
// Ok button |
|||
Observable.combineLatest([accountTextField.valid, bankTextField.valid]) |
|||
.flatMap { Observable.just($0.allSatisfy {$0}) } |
|||
.bind(onNext: { |
|||
self.getNameButton.isEnabled = $0 |
|||
self.getNameButton.backgroundColor = $0 ? .themeRed : .lightGray |
|||
}).disposed(by: disposeBag) |
|||
|
|||
balanceButton.rx.tap.bind { |
|||
self.view.endEditing(true) |
|||
}.disposed(by: disposeBag) |
|||
} |
|||
} |
@ -1,292 +0,0 @@ |
|||
// |
|||
// DomesticRemitViewModel.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import RxSwift |
|||
import RxCocoa |
|||
|
|||
class DomesticRemitViewModel: ViewModelType { |
|||
var presenter: DomesticRemitModuleInterface? |
|||
|
|||
struct Input { |
|||
let viewWillAppear: Driver<Void> |
|||
let showBalanceTrigger: Driver<Void> |
|||
let showRecentHistoryTrigger: Driver<Void> |
|||
let selectedBankIndex: Driver<Int> |
|||
let selectAutodebit: Driver<Void> |
|||
let selectBankTrigger: Driver<Void> |
|||
let amount: Driver<String> |
|||
let account: Driver<String> |
|||
let isValidAccount: Driver<Bool> |
|||
let mobile: Driver<String> |
|||
let getRecipientNameTrigger: Driver<Void> |
|||
let sendTrigger: Driver<Void> |
|||
} |
|||
|
|||
struct Output { |
|||
let isError: Driver<Error> |
|||
let isProgress: Driver<Bool> |
|||
let selectedAutodebit: Driver<Account?> |
|||
let fetchBankList: Driver<[Account]> |
|||
let selectedServiceFee: Driver<String?> |
|||
let selectedBank: Driver<BankInformation?> |
|||
let selectedRecipient: Driver<RecentRecipientModel?> |
|||
let getRecipientName: Driver<RecipientNameModel?> |
|||
let getInitialData: Driver<DomesticRemitModel?> |
|||
let getBalance: Driver<BalanceModel?> |
|||
let isAvailableRemit: Driver<Bool> |
|||
let successRemit: Driver<ResponseContainerObject<DomesticRemitResponseModel>> |
|||
let receiptTrigger: AnyObserver<DomesticRemitResponseModel> |
|||
} |
|||
|
|||
private let disposeBag = DisposeBag() |
|||
|
|||
private let progressLinker = PublishSubject<Bool>() |
|||
private let errorLinker = PublishSubject<Error>() |
|||
|
|||
private let selectedServiceFeeLinker = BehaviorSubject<String?>(value: nil) |
|||
private let selectedAutodebitLinker = BehaviorSubject<Account?>(value: nil) |
|||
private let selectedBankLinker = BehaviorSubject<BankInformation?>(value: nil) |
|||
private let selectedHistoryLinker = BehaviorSubject<RecentRecipientModel?>(value: nil) |
|||
private let getRecipientNameLinker = BehaviorSubject<RecipientNameModel?>(value: nil) |
|||
private let getInitialDataLinker = BehaviorSubject<DomesticRemitModel?>(value: nil) |
|||
private let getBalanceLinker = BehaviorSubject<BalanceModel?>(value: nil) |
|||
private let successRemitLinker = PublishSubject<ResponseContainerObject<DomesticRemitResponseModel>>() |
|||
private let getBankListLinker = BehaviorSubject<[Account]>(value: []) |
|||
|
|||
func transform(input: Input) -> Output { |
|||
|
|||
input.viewWillAppear.drive(onNext: { |
|||
let model = try? self.getInitialDataLinker.value() |
|||
if model == nil { |
|||
self.presenter?.fetchInformation() |
|||
} |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
input.showBalanceTrigger |
|||
.withLatestFrom(selectedAutodebitLinker.asDriverOnErrorJustComplete()) { $1 } |
|||
.drive(onNext: { |
|||
let fintechUseNumber = $0?.fintechUseNumber ?? "" |
|||
let type = $0?.type ?? "autodebit" |
|||
|
|||
self.presenter?.fetchBalance(type: type, fintechUseNumber: fintechUseNumber) |
|||
}).disposed(by: disposeBag) |
|||
|
|||
input.selectedBankIndex |
|||
.withLatestFrom(getBankListLinker.asDriverOnErrorJustComplete()) { (indexPath, bank) -> Account in |
|||
return bank[indexPath] |
|||
} |
|||
.drive(onNext: {[weak self] in |
|||
self?.getBalanceLinker.onNext(nil) |
|||
let model = $0 |
|||
self?.selectedAutodebitLinker.onNext(model) |
|||
if model.type == "wallet" { |
|||
let serviceFee = (try? self?.getInitialDataLinker.value())?.serviceFeeWallet |
|||
self?.selectedServiceFeeLinker.onNext(serviceFee) |
|||
self?.setBalance(with: BalanceModel( |
|||
balance: GMEDB.shared.user.string(.availableBalance)?.currencyToDecimal()) |
|||
) |
|||
} else { |
|||
let serviceFee = (try? self?.getInitialDataLinker.value())?.serviceFee |
|||
self?.selectedServiceFeeLinker.onNext(serviceFee) |
|||
} |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
input.selectAutodebit.drive(onNext: { |
|||
self.getBalanceLinker.onNext(nil) |
|||
self.presenter?.showTablePresenter(type: .autodebit) |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
input.selectBankTrigger.drive(onNext: {self.presenter?.showTablePresenter(type: .banks)}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
input.showRecentHistoryTrigger.drive(onNext: {self.presenter?.showTablePresenter(type: .histories)}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
let validateData = input.account |
|||
.withLatestFrom(selectedBankLinker.asDriverOnErrorJustComplete()) { ($0, $1)} |
|||
|
|||
input.getRecipientNameTrigger |
|||
.withLatestFrom(validateData) {$1} |
|||
.withLatestFrom(input.isValidAccount) { ($0, $1) } |
|||
.drive(onNext: { |
|||
let account = $0.0 |
|||
guard let bank = $0.1 else { return } |
|||
|
|||
if $1 { |
|||
self.presenter?.getRecipientName(account: account, bankCode: bank.bankCode ?? "") |
|||
} |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
let combinedInformation = Driver.combineLatest( |
|||
input.amount, |
|||
input.mobile, |
|||
input.account, |
|||
getRecipientNameLinker.asDriverOnErrorJustComplete(), |
|||
selectedBankLinker.asDriverOnErrorJustComplete(), |
|||
selectedAutodebitLinker.asDriverOnErrorJustComplete() |
|||
) { (amount, mobile, account, recipient, bank, autodebit) -> [String] in |
|||
let name = recipient?.name ?? "" |
|||
let bankCode = bank?.bankCode ?? "" |
|||
let fintechCode = autodebit?.fintechUseNumber ?? "" |
|||
let accountID = autodebit?.kftcAccountId ?? "" |
|||
let type = autodebit?.type ?? "" |
|||
|
|||
return [amount.stringRemovingComma(), mobile, account, name, bankCode, fintechCode, accountID, type] |
|||
} |
|||
|
|||
input.sendTrigger |
|||
.withLatestFrom(combinedInformation) {$1} |
|||
.drive(onNext: { |
|||
let amount = $0[0] |
|||
let mobile = $0[1] |
|||
let account = $0[2] |
|||
let name = $0[3] |
|||
let bankCode = $0[4] |
|||
let fintechUseNumber = $0[5] |
|||
let accountID = $0[6] |
|||
let type = $0[7] |
|||
|
|||
let isUseBiometric = KeyChain.shared.get(key: .biometricAuth) == "1" ? true : false |
|||
|
|||
let model = DomesticRemitRequestModel( |
|||
customerID: GMEDB.shared.user.string(.senderId) ?? "", |
|||
fintechID: fintechUseNumber, |
|||
accountID: accountID, |
|||
sendAmount: amount, |
|||
bankCode: bankCode, |
|||
accountNumber: account, |
|||
type: type, |
|||
name: name, |
|||
mobile: mobile, |
|||
isUseBiometric: isUseBiometric, |
|||
password: "" |
|||
) |
|||
|
|||
self.presenter?.send(with: model) |
|||
|
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
let balance = getBalanceLinker.flatMap {Observable.just($0?.balance)}.asDriverOnErrorJustComplete() |
|||
let serviceFee = selectedServiceFeeLinker.asDriverOnErrorJustComplete() |
|||
|
|||
let isAvailableRemit = Driver |
|||
.combineLatest(input.amount, serviceFee, balance) { (amountText, serviceFeeText, balanceText) -> Bool in |
|||
let amount = Int(amountText.extract(regex: "[0-9]")) ?? 0 |
|||
let serviceFee = Int(serviceFeeText ?? "1500") ?? 1500 |
|||
let realSendAmount = amount + serviceFee |
|||
|
|||
guard |
|||
let balance = balanceText, |
|||
let balanceNumber = Double(balance) else { |
|||
return amount > 9999 && amount <= 6500000 |
|||
} |
|||
return (realSendAmount <= Int(balanceNumber) ? true : false) && amount > 9999 && amount <= 6500000 |
|||
} |
|||
|
|||
let receiptTrigger = PublishSubject<DomesticRemitResponseModel>() |
|||
|
|||
receiptTrigger.asObservable().asDriverOnErrorJustComplete() |
|||
.drive(onNext: { |
|||
self.presenter?.goReceipt(with: $0) |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
return Output( |
|||
isError: errorLinker.asDriverOnErrorJustComplete(), |
|||
isProgress: progressLinker.asDriverOnErrorJustComplete(), |
|||
selectedAutodebit: selectedAutodebitLinker.asDriverOnErrorJustComplete(), |
|||
fetchBankList: getBankListLinker.asDriverOnErrorJustComplete(), |
|||
selectedServiceFee: selectedServiceFeeLinker.asDriverOnErrorJustComplete(), |
|||
selectedBank: selectedBankLinker.asDriverOnErrorJustComplete(), |
|||
selectedRecipient: selectedHistoryLinker.asDriverOnErrorJustComplete(), |
|||
getRecipientName: getRecipientNameLinker.asDriverOnErrorJustComplete(), |
|||
getInitialData: getInitialDataLinker.asDriverOnErrorJustComplete(), |
|||
getBalance: getBalanceLinker.asDriverOnErrorJustComplete(), |
|||
isAvailableRemit: isAvailableRemit, |
|||
successRemit: successRemitLinker.asDriverOnErrorJustComplete(), |
|||
receiptTrigger: receiptTrigger.asObserver() |
|||
) |
|||
} |
|||
} |
|||
|
|||
// MARK: DomesticRemit view interface |
|||
extension DomesticRemitViewModel: DomesticRemitViewModelInterface { |
|||
func setError(with error: Error) { |
|||
errorLinker.onNext(error) |
|||
} |
|||
|
|||
func progress(isShow: Bool) { |
|||
progressLinker.onNext(isShow) |
|||
} |
|||
|
|||
func setModel(with model: DomesticRemitModel) { |
|||
getInitialDataLinker.onNext(model) |
|||
guard let accounts = model.accounts else { return } |
|||
|
|||
getBankListLinker.onNext(accounts) |
|||
let selectedAccount = accounts.first(where: { $0.type == "wallet" }) |
|||
|
|||
if selectedAccount != nil { |
|||
let serviceFee = (try? getInitialDataLinker.value())?.serviceFeeWallet |
|||
selectedServiceFeeLinker.onNext(serviceFee) |
|||
setBalance(with: BalanceModel( |
|||
balance: GMEDB.shared.user.string(.availableBalance)?.currencyToDecimal()) |
|||
) |
|||
} |
|||
|
|||
selectedAutodebitLinker.onNext(selectedAccount) |
|||
|
|||
// if model.accounts?.count != 0 { |
|||
// selectedData(with: model.accounts?[0], type: .autodebit) |
|||
// } |
|||
} |
|||
|
|||
func selectedData(with model: TablePresenterProtocol?, type: DomesticRemitPresenter.ShowType) { |
|||
switch type { |
|||
case .banks: |
|||
let model = model as? BankInformation |
|||
selectedBankLinker.onNext(model) |
|||
|
|||
case .histories: |
|||
let model = model as? RecentRecipientModel |
|||
selectedBankLinker.onNext(model?.bank) |
|||
selectedHistoryLinker.onNext(model) |
|||
|
|||
case .autodebit: |
|||
let model = model as? Account |
|||
selectedAutodebitLinker.onNext(model) |
|||
if model?.type == "wallet" { |
|||
let serviceFee = (try? getInitialDataLinker.value())?.serviceFeeWallet |
|||
selectedServiceFeeLinker.onNext(serviceFee) |
|||
setBalance(with: BalanceModel( |
|||
balance: GMEDB.shared.user.string(.availableBalance)?.currencyToDecimal()) |
|||
) |
|||
} else { |
|||
let serviceFee = (try? getInitialDataLinker.value())?.serviceFee |
|||
selectedServiceFeeLinker.onNext(serviceFee) |
|||
} |
|||
} |
|||
} |
|||
|
|||
func setRecipientName(with model: RecipientNameModel) { |
|||
getRecipientNameLinker.onNext(model) |
|||
} |
|||
|
|||
func setBalance(with model: BalanceModel) { |
|||
getBalanceLinker.onNext(model) |
|||
} |
|||
|
|||
func successRemit(with model: ResponseContainerObject<DomesticRemitResponseModel>) { |
|||
successRemitLinker.onNext(model) |
|||
} |
|||
} |
@ -1,19 +0,0 @@ |
|||
// |
|||
// DomesticRemitViewModelInterface.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
protocol DomesticRemitViewModelInterface: class { |
|||
func setError(with error: Error) |
|||
func progress(isShow: Bool) |
|||
|
|||
func setModel(with model: DomesticRemitModel) |
|||
func selectedData(with model: TablePresenterProtocol?, type: DomesticRemitPresenter.ShowType) |
|||
func setRecipientName(with model: RecipientNameModel) |
|||
func setBalance(with model: BalanceModel) |
|||
|
|||
func successRemit(with model: ResponseContainerObject<DomesticRemitResponseModel>) |
|||
} |
@ -1,186 +0,0 @@ |
|||
// |
|||
// DomesticRemitWireframe.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import UIKit |
|||
|
|||
class DomesticRemitWireframe { |
|||
weak var view: UIViewController! |
|||
weak var output: DomesticRemitWireframeOutput? |
|||
|
|||
private var model: DomesticRemitRequestModel? |
|||
} |
|||
|
|||
extension DomesticRemitWireframe: DomesticRemitWireframeInput { |
|||
|
|||
var storyboardName: String {return "DomesticRemit"} |
|||
|
|||
func getMainView() -> UIViewController { |
|||
let service = DomesticRemitService() |
|||
let interactor = DomesticRemitInteractor(service: service) |
|||
let presenter = DomesticRemitPresenter() |
|||
let viewModel = DomesticRemitViewModel() |
|||
let viewController = viewControllerFromStoryboard(of: DomesticRemitViewController.self) |
|||
|
|||
output = presenter |
|||
|
|||
viewController.viewModel = viewModel |
|||
interactor.output = presenter |
|||
presenter.interactor = interactor |
|||
presenter.wireframe = self |
|||
presenter.viewModel = viewModel |
|||
|
|||
viewModel.presenter = presenter |
|||
|
|||
view = viewController |
|||
return viewController |
|||
} |
|||
|
|||
func open(on source: UIViewController) { |
|||
let vc = getMainView() |
|||
|
|||
source.navigationController?.pushViewController(vc, animated: true) |
|||
} |
|||
|
|||
func showTablePresenter(with model: [TablePresenterProtocol]?, type: DomesticRemitPresenter.ShowType) { |
|||
TablePresenterWireframe().openWith( |
|||
tag: type.rawValue, |
|||
delegate: self, |
|||
model: model, |
|||
source: view |
|||
) |
|||
} |
|||
|
|||
func showPaymentMode(with model: [Account]?) { |
|||
let wireframe = SelectPaymentWireframe() |
|||
wireframe.delegate = self |
|||
wireframe.openSelectPaymentUsingPanModal(with: model, in: view) |
|||
} |
|||
|
|||
func showRecentHistories() { |
|||
RecentHistoriesWireframe().open(delegate: self, on: view) |
|||
} |
|||
|
|||
func showBiometricAuth(with model: DomesticRemitRequestModel?) { |
|||
self.model = model |
|||
BiometricAuthenticationWireframe().openWithDelegate(on: view, delegate: self) |
|||
} |
|||
|
|||
func showOTP(with model: DomesticRemitRequestModel?) { |
|||
self.model = model |
|||
|
|||
SendMoneyCodeWireframe().open( |
|||
newValue: "", |
|||
requestmodel: model, |
|||
completion: { self.output?.setPassword($0) }, |
|||
source: view |
|||
) |
|||
} |
|||
|
|||
func showSecureKeypad(with model: DomesticRemitRequestModel?) { |
|||
self.model = model |
|||
let passwordVC = PasswordInputViewController() |
|||
passwordVC.enteredPassword = { value in |
|||
self.output?.setPassword(value) |
|||
} |
|||
passwordVC.modalPresentationStyle = .overFullScreen |
|||
self.view.present(passwordVC, animated: true) |
|||
} |
|||
|
|||
func goReceipt(with model: DomesticRemitResponseModel) { |
|||
if let navigation = self.view.navigationController { |
|||
SendMoneyReceiptWireframe().openReciept( |
|||
type: .domestic, |
|||
transactionId: model.transactionID ?? "", |
|||
source: navigation |
|||
) |
|||
} |
|||
} |
|||
} |
|||
|
|||
extension DomesticRemitWireframe: TablePresenterDelegate { |
|||
func tablePresenterView(_ viewController: TablePresenterViewController) -> TablePresenterConfiguration { |
|||
return TablePresenterConfiguration( |
|||
presenterTitle: "select_bank_text".localized(), |
|||
closeButtonTitle: "penny_test_close_text".localized(), |
|||
notFoundTitle: "no_bank_found_text".localized(), |
|||
searchBarPlaceHolder: "search_bank_text".localized() |
|||
) |
|||
} |
|||
|
|||
func tablePresenterView( |
|||
_ viewController: TablePresenterViewController, |
|||
didSelectModel model: TablePresenterProtocol? |
|||
) { |
|||
guard let type = DomesticRemitPresenter.ShowType(rawValue: viewController.view.tag) else { return } |
|||
|
|||
output?.selectedData(with: model, type: type) |
|||
} |
|||
} |
|||
|
|||
extension DomesticRemitWireframe: RecentHistoriesDelegate { |
|||
func recentHistories( |
|||
_ viewController: RecentHistoriesViewController, |
|||
didSelectHistory: RecentRecipientModel |
|||
) { |
|||
output?.selectedData(with: didSelectHistory, type: .histories) |
|||
} |
|||
} |
|||
|
|||
extension DomesticRemitWireframe: BiometricAuthenticationViewControllerDelegate { |
|||
func viewController( |
|||
_ viewController: BiometricAuthenticationViewController, |
|||
informationTitleLabel titleLabel: UILabel, |
|||
authenticationButton button: UIButton) { |
|||
titleLabel.text = "bio_sendmoney_intro_text".localized() |
|||
button.setTitle("send_money_text".localized(), for: .normal) |
|||
} |
|||
|
|||
func didComplete(_ viewController: BiometricAuthenticationViewController) { |
|||
viewController.dismiss(animated: true) { |
|||
guard let encryptedPW = KeyChain.shared.get(key: .password) else { |
|||
MainWireframe.logoutWarningAlert(message: "To use biometrics authentication you have to login again.") |
|||
return |
|||
} |
|||
self.output?.setPassword(encryptedPW) |
|||
} |
|||
} |
|||
|
|||
func viewController( |
|||
_ viewController: BiometricAuthenticationViewController, |
|||
didFailWithError error: BiometricAuthenticationError, |
|||
errorMessage: String? |
|||
) { |
|||
viewController.dismiss(animated: true) { |
|||
switch error { |
|||
case .userFallback: |
|||
if self.model?.type == "autodebit" { |
|||
self.showOTP(with: self.model) |
|||
} else { |
|||
self.showSecureKeypad(with: self.model) |
|||
} |
|||
case .biometryNotEnrolled, .notBeConfigured, .biometryNotAvailable: |
|||
self.view.alert(type: .error, message: error.message) |
|||
default: |
|||
break |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
extension DomesticRemitWireframe: SelectPaymentDelegate { |
|||
func selectPayment(_ viewController: SelectPaymentViewController, selectedAccount: Account) { |
|||
viewController.dismiss(animated: true) { |
|||
self.output?.selectedData(with: selectedAccount, type: .autodebit) |
|||
} |
|||
} |
|||
|
|||
func selectPayment(_ viewController: SelectPaymentViewController, error: Error) { |
|||
} |
|||
} |
|||
|
@ -1,24 +0,0 @@ |
|||
// |
|||
// DomesticRemitWireframeInputOutput.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
|
|||
protocol DomesticRemitWireframeInput: WireframeInput { |
|||
func showTablePresenter(with model: [TablePresenterProtocol]?, type: DomesticRemitPresenter.ShowType) |
|||
func showPaymentMode(with model: [Account]?) |
|||
func showRecentHistories() |
|||
func showBiometricAuth(with model: DomesticRemitRequestModel?) |
|||
func showOTP(with model: DomesticRemitRequestModel?) |
|||
func showSecureKeypad(with model: DomesticRemitRequestModel?) |
|||
func goReceipt(with model: DomesticRemitResponseModel) |
|||
} |
|||
|
|||
protocol DomesticRemitWireframeOutput: class { |
|||
func selectedData(with model: TablePresenterProtocol?, type: DomesticRemitPresenter.ShowType) |
|||
func setPassword(_ encryptedPW: String) |
|||
} |
@ -1,40 +0,0 @@ |
|||
// |
|||
// RecentHistoriesInteractor.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
|
|||
class RecentHistoriesInteractor { |
|||
|
|||
// MARK: Properties |
|||
|
|||
weak var output: RecentHistoriesInteractorOutput? |
|||
private let service: RecentHistoriesServiceType |
|||
|
|||
// MARK: Initialization |
|||
|
|||
init(service: RecentHistoriesServiceType) { |
|||
self.service = service |
|||
} |
|||
|
|||
} |
|||
|
|||
// MARK: RecentHistories interactor input interface |
|||
|
|||
extension RecentHistoriesInteractor: RecentHistoriesInteractorInput { |
|||
func fetchHistories( |
|||
from: String = "", |
|||
to: String = "" |
|||
) { |
|||
service.fetchHistories( |
|||
from: from, |
|||
to: to, |
|||
success: {self.output?.setHistories(with: $0)}, |
|||
failure: {self.output?.setError(with:$0)} |
|||
) |
|||
} |
|||
} |
@ -1,19 +0,0 @@ |
|||
// |
|||
// RecentHistoriesInteractorIO.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
protocol RecentHistoriesInteractorInput: class { |
|||
func fetchHistories( |
|||
from: String, |
|||
to: String |
|||
) |
|||
} |
|||
|
|||
protocol RecentHistoriesInteractorOutput: class { |
|||
func setHistories(with model: [RecentRecipientModel]) |
|||
func setError(with error: Error) |
|||
} |
@ -1,35 +0,0 @@ |
|||
// |
|||
// RecentRecipientModel.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import ObjectMapper |
|||
|
|||
struct RecentRecipientModel: Mappable { |
|||
var bank: BankInformation? |
|||
var account: String? |
|||
var name: String? |
|||
|
|||
init?(map: Map) { |
|||
|
|||
} |
|||
|
|||
mutating func mapping(map: Map) { |
|||
bank <- map["bank"] |
|||
account <- map["recipient_account"] |
|||
name <- map["recipient_name"] |
|||
} |
|||
} |
|||
|
|||
extension RecentRecipientModel: TablePresenterProtocol { |
|||
var cellTitle: String? { |
|||
return name |
|||
} |
|||
|
|||
var cellImage: UIImage? { |
|||
return nil |
|||
} |
|||
} |
@ -1,21 +0,0 @@ |
|||
// |
|||
// RecentHistoriesService.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
|
|||
class RecentHistoriesService: RecentHistoriesServiceType { |
|||
func fetchHistories( |
|||
from: String = "", |
|||
to: String = "", |
|||
success: @escaping ([RecentRecipientModel]) -> Void, |
|||
failure: @escaping (Error) -> Void |
|||
) { |
|||
APIRouter.getRecentHistories(from: from, to: to).json(success: success, failure: failure) |
|||
} |
|||
|
|||
} |
@ -1,16 +0,0 @@ |
|||
// |
|||
// RecentHistoriesServiceType.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
protocol RecentHistoriesServiceType: class, ApiServiceType { |
|||
func fetchHistories( |
|||
from: String, |
|||
to: String, |
|||
success: @escaping ([RecentRecipientModel]) -> Void, |
|||
failure: @escaping (Error) -> Void |
|||
) |
|||
} |
@ -1,17 +0,0 @@ |
|||
// |
|||
// RecentHistoriesModuleInterface.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
protocol RecentHistoriesModuleInterface: class { |
|||
func fetchHistories( |
|||
from: String, |
|||
to: String |
|||
) |
|||
|
|||
func presentDatePicker(completion: ((_ from: String?, _ to: String?) -> Void)?) |
|||
|
|||
} |
@ -1,51 +0,0 @@ |
|||
// |
|||
// RecentHistoriesPresenter.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
|
|||
class RecentHistoriesPresenter { |
|||
|
|||
// MARK: Properties |
|||
weak var viewModel: RecentHistoriesViewModelInterface? |
|||
var interactor: RecentHistoriesInteractorInput? |
|||
var wireframe: RecentHistoriesWireframeInput? |
|||
|
|||
} |
|||
|
|||
// MARK: RecentHistories module interface |
|||
extension RecentHistoriesPresenter: RecentHistoriesModuleInterface { |
|||
func fetchHistories( |
|||
from: String = "", |
|||
to: String = "" |
|||
) { |
|||
viewModel?.progress(isShow: true) |
|||
interactor?.fetchHistories(from: from, to: to) |
|||
} |
|||
|
|||
func presentDatePicker(completion: ((_ from: String?, _ to: String?) -> Void)?) { |
|||
wireframe?.presentDatePicker(completion: completion) |
|||
} |
|||
} |
|||
|
|||
// MARK: RecentHistories interactor output interface |
|||
extension RecentHistoriesPresenter: RecentHistoriesInteractorOutput { |
|||
func setHistories(with model: [RecentRecipientModel]) { |
|||
viewModel?.progress(isShow: false) |
|||
viewModel?.setHistories(with: model) |
|||
} |
|||
|
|||
func setError(with error: Error) { |
|||
viewModel?.progress(isShow: false) |
|||
viewModel?.setError(with: error) |
|||
} |
|||
} |
|||
|
|||
// MARK: RecentHistories wireframe output interface |
|||
extension RecentHistoriesPresenter: RecentHistoriesWireframeOutput { |
|||
|
|||
} |
@ -1,23 +0,0 @@ |
|||
// |
|||
// RecentRecipientCell.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import UIKit |
|||
|
|||
class RecentRecipientCell: UITableViewCell { |
|||
@IBOutlet private weak var nameLabel: UILabel! |
|||
@IBOutlet private weak var bankLabel: UILabel! |
|||
@IBOutlet private weak var accountLabel: UILabel! |
|||
@IBOutlet private weak var bankImageView: UIImageView! |
|||
|
|||
func setModel(with model: RecentRecipientModel) { |
|||
nameLabel.text = model.name |
|||
accountLabel.text = model.account |
|||
bankLabel.text = model.bank?.bankName |
|||
bankImageView.image = BankEnum(rawValue: model.bank?.bankCode ?? "")?.ciImage |
|||
} |
|||
} |
@ -1,315 +0,0 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="HSb-ou-7T5"> |
|||
<device id="retina4_7" orientation="portrait" appearance="light"/> |
|||
<dependencies> |
|||
<deployment identifier="iOS"/> |
|||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/> |
|||
<capability name="Named colors" minToolsVersion="9.0"/> |
|||
<capability name="Safe area layout guides" minToolsVersion="9.0"/> |
|||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> |
|||
</dependencies> |
|||
<customFonts key="customFonts"> |
|||
<array key="SanFranciscoDisplay-Medium.otf"> |
|||
<string>SanFranciscoDisplay-Medium</string> |
|||
</array> |
|||
<array key="SanFranciscoDisplay-Regular.otf"> |
|||
<string>SanFranciscoDisplay-Regular</string> |
|||
</array> |
|||
</customFonts> |
|||
<scenes> |
|||
<!--RecentHistories--> |
|||
<scene sceneID="R60-Pu-Hpy"> |
|||
<objects> |
|||
<viewController storyboardIdentifier="RecentHistoriesViewController" title="RecentHistories" modalTransitionStyle="crossDissolve" modalPresentationStyle="overFullScreen" id="HSb-ou-7T5" customClass="RecentHistoriesViewController" customModule="GME_Remit" sceneMemberID="viewController"> |
|||
<view key="view" contentMode="scaleToFill" id="9Uc-9s-KgO"> |
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/> |
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> |
|||
<subviews> |
|||
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9jL-Y3-Li7"> |
|||
<rect key="frame" x="0.0" y="200" width="375" height="467"/> |
|||
<subviews> |
|||
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Xuy-dc-FlA"> |
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/> |
|||
<subviews> |
|||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EPv-JI-308"> |
|||
<rect key="frame" x="0.0" y="0.0" width="44" height="44"/> |
|||
<color key="tintColor" name="ThemeBlack"/> |
|||
<state key="normal" image="ic_cancel"> |
|||
<color key="titleColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
</state> |
|||
</button> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Recent Recipients" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Gh5-V7-h0V"> |
|||
<rect key="frame" x="130.5" y="14" width="114.5" height="16.5"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
<color key="backgroundColor" name="ThemeMainBackground"/> |
|||
<constraints> |
|||
<constraint firstItem="EPv-JI-308" firstAttribute="leading" secondItem="Xuy-dc-FlA" secondAttribute="leading" id="3bL-5Z-mNf"/> |
|||
<constraint firstItem="Gh5-V7-h0V" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="EPv-JI-308" secondAttribute="trailing" constant="10" id="Cqj-7g-wjE"/> |
|||
<constraint firstItem="EPv-JI-308" firstAttribute="centerY" secondItem="Xuy-dc-FlA" secondAttribute="centerY" id="O0F-7C-bJC"/> |
|||
<constraint firstAttribute="height" constant="44" id="Sw4-dj-PmZ"/> |
|||
<constraint firstItem="EPv-JI-308" firstAttribute="height" secondItem="Xuy-dc-FlA" secondAttribute="height" id="Wca-FQ-XLz"/> |
|||
<constraint firstItem="Gh5-V7-h0V" firstAttribute="centerY" secondItem="Xuy-dc-FlA" secondAttribute="centerY" id="Yaf-Bn-vCI"/> |
|||
<constraint firstItem="EPv-JI-308" firstAttribute="width" secondItem="Xuy-dc-FlA" secondAttribute="height" multiplier="1:1" id="cc8-Rz-jSQ"/> |
|||
<constraint firstItem="Gh5-V7-h0V" firstAttribute="centerX" secondItem="Xuy-dc-FlA" secondAttribute="centerX" id="kvf-d8-JT3"/> |
|||
</constraints> |
|||
</view> |
|||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ean-iy-xy9"> |
|||
<rect key="frame" x="10" y="44" width="355" height="50"/> |
|||
<subviews> |
|||
<searchBar contentMode="redraw" searchBarStyle="minimal" placeholder="search" translatesAutoresizingMaskIntoConstraints="NO" id="vEO-cI-U7T"> |
|||
<rect key="frame" x="0.0" y="0.0" width="305" height="50"/> |
|||
<textInputTraits key="textInputTraits"/> |
|||
</searchBar> |
|||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ua4-FA-oLE"> |
|||
<rect key="frame" x="305" y="0.0" width="50" height="50"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="4V1-zf-HHl"/> |
|||
<constraint firstAttribute="width" constant="50" id="sWc-xp-mml"/> |
|||
</constraints> |
|||
<state key="normal" image="ic_calender"/> |
|||
</button> |
|||
</subviews> |
|||
</stackView> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Jsr-2H-Myx"> |
|||
<rect key="frame" x="7.5" y="94" width="360" height="35"/> |
|||
<subviews> |
|||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8LO-G4-CMW"> |
|||
<rect key="frame" x="10" y="0.0" width="340" height="35"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="90P-TB-KnT"> |
|||
<rect key="frame" x="107" y="-7.5" width="126" height="50"/> |
|||
<subviews> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fG3-MO-Gxx"> |
|||
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="16"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="~" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3op-mZ-aj4"> |
|||
<rect key="frame" x="58" y="0.0" width="10" height="50"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="16"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8B4-ov-sul"> |
|||
<rect key="frame" x="76" y="0.0" width="50" height="50"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="16"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
</stackView> |
|||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xGJ-l2-4gF"> |
|||
<rect key="frame" x="315" y="10" width="15" height="15"/> |
|||
<constraints> |
|||
<constraint firstAttribute="width" constant="15" id="KPB-Sg-RlG"/> |
|||
<constraint firstAttribute="height" constant="15" id="rhL-pb-B9n"/> |
|||
</constraints> |
|||
<state key="normal" title="Button" image="ic_error"/> |
|||
<connections> |
|||
<action selector="touchCloseCalandarButton:" destination="HSb-ou-7T5" eventType="touchUpInside" id="ehG-lR-Oem"/> |
|||
</connections> |
|||
</button> |
|||
</subviews> |
|||
<color key="backgroundColor" name="ThemeMainBackground"/> |
|||
<constraints> |
|||
<constraint firstItem="xGJ-l2-4gF" firstAttribute="centerY" secondItem="8LO-G4-CMW" secondAttribute="centerY" id="1BC-1u-hDs"/> |
|||
<constraint firstAttribute="trailing" secondItem="xGJ-l2-4gF" secondAttribute="trailing" constant="10" id="95D-Y9-lfa"/> |
|||
<constraint firstItem="90P-TB-KnT" firstAttribute="centerY" secondItem="8LO-G4-CMW" secondAttribute="centerY" id="HlE-AG-yhP"/> |
|||
<constraint firstItem="90P-TB-KnT" firstAttribute="centerX" secondItem="8LO-G4-CMW" secondAttribute="centerX" id="mCk-8Q-ZkO"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
<color key="backgroundColor" name="ThemeMainBackground"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="35" id="BV1-cX-hEA"/> |
|||
<constraint firstItem="8LO-G4-CMW" firstAttribute="top" secondItem="Jsr-2H-Myx" secondAttribute="top" id="EkN-AX-55n"/> |
|||
<constraint firstItem="8LO-G4-CMW" firstAttribute="leading" secondItem="Jsr-2H-Myx" secondAttribute="leading" constant="10" id="LIK-5b-72r"/> |
|||
<constraint firstAttribute="trailing" secondItem="8LO-G4-CMW" secondAttribute="trailing" constant="10" id="fpI-u9-O35"/> |
|||
<constraint firstAttribute="bottom" secondItem="8LO-G4-CMW" secondAttribute="bottom" id="kqR-Qn-oHm"/> |
|||
</constraints> |
|||
</view> |
|||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="vSd-Cn-NtH"> |
|||
<rect key="frame" x="10" y="134" width="355" height="323"/> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<color key="tintColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<view key="tableFooterView" contentMode="scaleToFill" id="Jc0-AE-AKV"> |
|||
<rect key="frame" x="0.0" y="126" width="355" height="44"/> |
|||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> |
|||
<subviews> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Not found" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DSX-pB-voq"> |
|||
<rect key="frame" x="0.0" y="0.0" width="355" height="44"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="17"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="trailing" secondItem="DSX-pB-voq" secondAttribute="trailing" id="DaZ-1h-pAY"/> |
|||
<constraint firstItem="DSX-pB-voq" firstAttribute="top" secondItem="Jc0-AE-AKV" secondAttribute="top" id="bGf-IH-G4v"/> |
|||
<constraint firstItem="DSX-pB-voq" firstAttribute="leading" secondItem="Jc0-AE-AKV" secondAttribute="leading" id="qQc-WR-GOE"/> |
|||
<constraint firstAttribute="bottom" secondItem="DSX-pB-voq" secondAttribute="bottom" id="yIF-Pg-Za6"/> |
|||
</constraints> |
|||
</view> |
|||
<prototypes> |
|||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="5" indentationWidth="5" reuseIdentifier="RecentRecipientCell" rowHeight="70" id="X2M-ta-xHv" customClass="RecentRecipientCell" customModule="GME_Remit" customModuleProvider="target"> |
|||
<rect key="frame" x="0.0" y="28" width="355" height="70"/> |
|||
<autoresizingMask key="autoresizingMask"/> |
|||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="X2M-ta-xHv" id="et9-GJ-ooJ"> |
|||
<rect key="frame" x="0.0" y="0.0" width="355" height="70"/> |
|||
<autoresizingMask key="autoresizingMask"/> |
|||
<subviews> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FkF-ac-dcc"> |
|||
<rect key="frame" x="20" y="10" width="315" height="50"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="4lw-Z7-vab"> |
|||
<rect key="frame" x="0.0" y="0.0" width="315" height="50"/> |
|||
<subviews> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="James Kim" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="ilt-ZQ-e17"> |
|||
<rect key="frame" x="0.0" y="0.0" width="63" height="50"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<stackView opaque="NO" contentMode="scaleToFill" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="6t6-J6-oAY"> |
|||
<rect key="frame" x="68" y="0.0" width="157.5" height="50"/> |
|||
<subviews> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vmN-5a-KJV"> |
|||
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/> |
|||
<subviews> |
|||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ibk" translatesAutoresizingMaskIntoConstraints="NO" id="Blw-jf-U4G"> |
|||
<rect key="frame" x="5" y="5" width="40" height="40"/> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="width" secondItem="Blw-jf-U4G" secondAttribute="height" multiplier="1:1" id="92z-OM-Pje"/> |
|||
</constraints> |
|||
</imageView> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="trailing" secondItem="Blw-jf-U4G" secondAttribute="trailing" constant="5" id="90v-q8-bJa"/> |
|||
<constraint firstAttribute="bottom" secondItem="Blw-jf-U4G" secondAttribute="bottom" constant="5" id="UtA-KL-jDk"/> |
|||
<constraint firstItem="Blw-jf-U4G" firstAttribute="leading" secondItem="vmN-5a-KJV" secondAttribute="leading" constant="5" id="Wiy-xb-d10"/> |
|||
<constraint firstItem="Blw-jf-U4G" firstAttribute="top" secondItem="vmN-5a-KJV" secondAttribute="top" constant="5" id="l60-KM-BaS"/> |
|||
</constraints> |
|||
</view> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Korea Development Bank(KDB)" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="9NA-kr-brd"> |
|||
<rect key="frame" x="52" y="0.0" width="105.5" height="50"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
</stackView> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="110223458044" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="sSB-S3-hHb"> |
|||
<rect key="frame" x="230.5" y="0.0" width="84.5" height="50"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/> |
|||
<color key="textColor" name="ThemeText"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
<constraints> |
|||
<constraint firstItem="6t6-J6-oAY" firstAttribute="width" secondItem="4lw-Z7-vab" secondAttribute="width" multiplier="0.5:1" id="Ikg-Ch-XlP"/> |
|||
<constraint firstItem="ilt-ZQ-e17" firstAttribute="width" secondItem="4lw-Z7-vab" secondAttribute="width" multiplier="0.2:1" id="PGQ-4D-5e2"/> |
|||
</constraints> |
|||
</stackView> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="4lw-Z7-vab" firstAttribute="leading" secondItem="FkF-ac-dcc" secondAttribute="leading" id="8HL-J5-Wqa"/> |
|||
<constraint firstAttribute="trailing" secondItem="4lw-Z7-vab" secondAttribute="trailing" id="9zs-y8-CKC"/> |
|||
<constraint firstAttribute="bottom" secondItem="4lw-Z7-vab" secondAttribute="bottom" id="Pwj-Nc-aar"/> |
|||
<constraint firstAttribute="height" constant="50" id="tMn-UC-LBh"/> |
|||
<constraint firstItem="4lw-Z7-vab" firstAttribute="top" secondItem="FkF-ac-dcc" secondAttribute="top" id="vO4-Ae-DCb"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="trailing" secondItem="FkF-ac-dcc" secondAttribute="trailing" constant="20" id="TSh-jG-UJ1"/> |
|||
<constraint firstItem="FkF-ac-dcc" firstAttribute="leading" secondItem="et9-GJ-ooJ" secondAttribute="leading" constant="20" id="XEG-qZ-l5W"/> |
|||
<constraint firstItem="FkF-ac-dcc" firstAttribute="top" secondItem="et9-GJ-ooJ" secondAttribute="top" constant="10" id="dQ3-0N-ZTj"/> |
|||
<constraint firstAttribute="bottom" secondItem="FkF-ac-dcc" secondAttribute="bottom" constant="10" id="ftf-QG-zjO"/> |
|||
</constraints> |
|||
</tableViewCellContentView> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<connections> |
|||
<outlet property="accountLabel" destination="sSB-S3-hHb" id="HfU-EG-pNP"/> |
|||
<outlet property="bankImageView" destination="Blw-jf-U4G" id="YjF-2c-8EB"/> |
|||
<outlet property="bankLabel" destination="9NA-kr-brd" id="k1u-eU-s6k"/> |
|||
<outlet property="nameLabel" destination="ilt-ZQ-e17" id="cwJ-cI-NQp"/> |
|||
</connections> |
|||
</tableViewCell> |
|||
</prototypes> |
|||
</tableView> |
|||
</subviews> |
|||
<color key="backgroundColor" name="ThemeMainBackground"/> |
|||
<constraints> |
|||
<constraint firstItem="vSd-Cn-NtH" firstAttribute="leading" secondItem="9jL-Y3-Li7" secondAttribute="leading" constant="10" id="4e9-7p-1hF"/> |
|||
<constraint firstAttribute="bottom" secondItem="vSd-Cn-NtH" secondAttribute="bottom" constant="10" id="5uw-xa-P0A"/> |
|||
<constraint firstItem="Xuy-dc-FlA" firstAttribute="top" secondItem="9jL-Y3-Li7" secondAttribute="top" id="8BB-ZR-xGS"/> |
|||
<constraint firstAttribute="trailing" secondItem="Jsr-2H-Myx" secondAttribute="trailing" constant="7.5" id="ADu-o6-B32"/> |
|||
<constraint firstAttribute="trailing" secondItem="vSd-Cn-NtH" secondAttribute="trailing" constant="10" id="Aps-rw-KLW"/> |
|||
<constraint firstItem="Ean-iy-xy9" firstAttribute="leading" secondItem="9jL-Y3-Li7" secondAttribute="leading" constant="10" id="CIL-AH-cfT"/> |
|||
<constraint firstItem="Ean-iy-xy9" firstAttribute="top" secondItem="Xuy-dc-FlA" secondAttribute="bottom" id="Val-z4-Y6a"/> |
|||
<constraint firstAttribute="trailing" secondItem="Xuy-dc-FlA" secondAttribute="trailing" id="Wru-8H-EHe"/> |
|||
<constraint firstAttribute="trailing" secondItem="Ean-iy-xy9" secondAttribute="trailing" constant="10" id="adi-8C-sFa"/> |
|||
<constraint firstItem="Jsr-2H-Myx" firstAttribute="leading" secondItem="9jL-Y3-Li7" secondAttribute="leading" constant="7.5" id="nS5-gN-E2j"/> |
|||
<constraint firstItem="Xuy-dc-FlA" firstAttribute="leading" secondItem="9jL-Y3-Li7" secondAttribute="leading" id="qbJ-S8-MQa"/> |
|||
<constraint firstItem="vSd-Cn-NtH" firstAttribute="top" secondItem="Jsr-2H-Myx" secondAttribute="bottom" constant="5" id="t9r-ay-d7l"/> |
|||
<constraint firstItem="Jsr-2H-Myx" firstAttribute="top" secondItem="Ean-iy-xy9" secondAttribute="bottom" id="zcG-CI-ZBq"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.6972121147260274" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="9jL-Y3-Li7" firstAttribute="height" secondItem="9Uc-9s-KgO" secondAttribute="height" multiplier="0.7:1" id="CBH-Co-zMI"/> |
|||
<constraint firstItem="9jL-Y3-Li7" firstAttribute="bottom" secondItem="9Uc-9s-KgO" secondAttribute="bottom" id="bN3-L2-s0a"/> |
|||
<constraint firstItem="9jL-Y3-Li7" firstAttribute="leading" secondItem="O1T-1R-Sun" secondAttribute="leading" id="s7T-ca-Gcf"/> |
|||
<constraint firstItem="9jL-Y3-Li7" firstAttribute="trailing" secondItem="O1T-1R-Sun" secondAttribute="trailing" id="wYT-bV-md2"/> |
|||
</constraints> |
|||
<viewLayoutGuide key="safeArea" id="O1T-1R-Sun"/> |
|||
</view> |
|||
<connections> |
|||
<outlet property="calendarButton" destination="ua4-FA-oLE" id="gUc-xa-SJP"/> |
|||
<outlet property="closeButton" destination="EPv-JI-308" id="Ymx-DI-ooD"/> |
|||
<outlet property="closeCalandarButton" destination="xGJ-l2-4gF" id="u3l-h0-0FM"/> |
|||
<outlet property="endDateLabel" destination="8B4-ov-sul" id="Nbu-gl-KKA"/> |
|||
<outlet property="mainView" destination="9jL-Y3-Li7" id="rU2-JH-1ys"/> |
|||
<outlet property="notFoundLabel" destination="DSX-pB-voq" id="RA9-u9-XWm"/> |
|||
<outlet property="periodView" destination="Jsr-2H-Myx" id="9il-be-KHl"/> |
|||
<outlet property="periodViewHeightConstraint" destination="BV1-cX-hEA" id="xvF-yB-gnA"/> |
|||
<outlet property="perioidContentView" destination="8LO-G4-CMW" id="8Zn-JX-Ugq"/> |
|||
<outlet property="searchBar" destination="vEO-cI-U7T" id="TZg-36-zRf"/> |
|||
<outlet property="startDateLabel" destination="fG3-MO-Gxx" id="HAC-hJ-5rZ"/> |
|||
<outlet property="tableView" destination="vSd-Cn-NtH" id="yf9-1x-1U0"/> |
|||
<outlet property="titleLabel" destination="Gh5-V7-h0V" id="2ts-z8-NQ9"/> |
|||
</connections> |
|||
</viewController> |
|||
<placeholder placeholderIdentifier="IBFirstResponder" id="8je-5K-XuW" userLabel="First Responder" sceneMemberID="firstResponder"/> |
|||
</objects> |
|||
<point key="canvasLocation" x="-92" y="232.53373313343329"/> |
|||
</scene> |
|||
</scenes> |
|||
<resources> |
|||
<image name="ibk" width="1080" height="728"/> |
|||
<image name="ic_calender" width="25" height="25"/> |
|||
<image name="ic_cancel" width="12" height="12"/> |
|||
<image name="ic_error" width="55" height="55"/> |
|||
<namedColor name="ThemeBlack"> |
|||
<color red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> |
|||
</namedColor> |
|||
<namedColor name="ThemeMainBackground"> |
|||
<color red="0.097999997437000275" green="0.097999997437000275" blue="0.097999997437000275" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> |
|||
</namedColor> |
|||
<namedColor name="ThemeText"> |
|||
<color white="0.80299997329711914" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
</namedColor> |
|||
</resources> |
|||
<color key="tintColor" red="0.78177064659999995" green="0.55228364470000002" blue="0.018981300289999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> |
|||
</document> |
@ -1,196 +0,0 @@ |
|||
// |
|||
// RecentHistoriesViewController.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import UIKit |
|||
import RxSwift |
|||
import RxCocoa |
|||
import IQKeyboardManagerSwift |
|||
|
|||
protocol RecentHistoriesDelegate: class { |
|||
func recentHistories( |
|||
_ viewController: RecentHistoriesViewController, |
|||
didSelectHistory: RecentRecipientModel |
|||
) |
|||
} |
|||
|
|||
class RecentHistoriesViewController: UIViewController { |
|||
|
|||
// MARK: Properties |
|||
var viewModel: RecentHistoriesViewModel! |
|||
|
|||
weak var delegate: RecentHistoriesDelegate? |
|||
|
|||
private let disposeBag = DisposeBag() |
|||
// MARK: Computed Properties |
|||
|
|||
// MARK: IBOutlets |
|||
|
|||
@IBOutlet private weak var calendarButton: UIButton! |
|||
@IBOutlet private weak var searchBar: UISearchBar! |
|||
@IBOutlet private weak var tableView: UITableView! |
|||
@IBOutlet private weak var closeButton: UIButton! |
|||
@IBOutlet private weak var titleLabel: UILabel! |
|||
@IBOutlet private weak var notFoundLabel: UILabel! |
|||
@IBOutlet private weak var mainView: UIView! |
|||
|
|||
@IBOutlet private weak var perioidContentView: UIView! |
|||
@IBOutlet private weak var periodView: UIView! |
|||
@IBOutlet private weak var startDateLabel: UILabel! |
|||
@IBOutlet private weak var endDateLabel: UILabel! |
|||
@IBOutlet private weak var closeCalandarButton: UIButton! |
|||
|
|||
@IBOutlet private weak var periodViewHeightConstraint: NSLayoutConstraint! |
|||
|
|||
private let impact = UISelectionFeedbackGenerator() |
|||
|
|||
// MARK: VC's Life cycle |
|||
override func viewDidLoad() { |
|||
super.viewDidLoad() |
|||
setup() |
|||
setMultilanguages() |
|||
} |
|||
|
|||
override func viewWillAppear(_ animated: Bool) { |
|||
super.viewWillAppear(animated) |
|||
|
|||
mainView.bottomToOrigin(duration: 0.1) |
|||
IQKeyboardManager.shared.enable = false |
|||
|
|||
impact.selectionChanged() |
|||
} |
|||
|
|||
override func viewWillDisappear(_ animated: Bool) { |
|||
super.viewWillDisappear(animated) |
|||
IQKeyboardManager.shared.enable = true |
|||
view.endEditing(true) |
|||
} |
|||
|
|||
// MARK: IBActions |
|||
@IBAction func touchCloseCalandarButton(_ sender: UIButton) { |
|||
startDateLabel.text?.removeAll() |
|||
endDateLabel.text?.removeAll() |
|||
setPeriodViewStatus(isHidden: true) |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
// MARK: Other Functions |
|||
extension RecentHistoriesViewController { |
|||
private func setMultilanguages() { |
|||
titleLabel.text = "recent_recipients_text".localized() |
|||
searchBar.placeholder = "search_text".localized() |
|||
notFoundLabel.text = "no_result_found_text".localized() |
|||
} |
|||
|
|||
private func setup() { |
|||
// all setup should be done here |
|||
tableView.rx.setDelegate(self).disposed(by: disposeBag) |
|||
|
|||
setBinding() |
|||
setPeriodViewStatus(isHidden: true) |
|||
mainView.layer.cornerRadius = 5 |
|||
} |
|||
|
|||
private func setBinding() { |
|||
let viewWillAppear = rx.sentMessage(#selector(UIViewController.viewWillAppear(_:))) |
|||
.mapToVoid() |
|||
.asDriverOnErrorJustComplete() |
|||
|
|||
let input = RecentHistoriesViewModel.Input( |
|||
viewWillAppear: viewWillAppear, |
|||
filterText: searchBar.rx.text.asDriverOnErrorJustComplete(), |
|||
selectTrigger: tableView.rx.itemSelected.asDriver(), |
|||
calendarTrigger: calendarButton.rx.tap.asDriver(), |
|||
closeCalandarTrigger: closeCalandarButton.rx.tap.asDriver() |
|||
) |
|||
let output = viewModel.transform(input: input) |
|||
|
|||
output.isError |
|||
.drive( |
|||
onNext: { self.alert(type: .error, message: $0.localizedDescription) } |
|||
).disposed(by: disposeBag) |
|||
|
|||
output.isProgress |
|||
.drive( |
|||
onNext: { $0 ? self.showProgressHud() : self.hideProgressHud() } |
|||
).disposed(by: disposeBag) |
|||
|
|||
output.histories |
|||
.map { $0.count != 0 } |
|||
.drive(self.notFoundLabel.rx.isHidden) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output |
|||
.histories.drive( |
|||
tableView.rx.items(cellIdentifier: "RecentRecipientCell") |
|||
) { (_, element: RecentRecipientModel, cell: RecentRecipientCell) in |
|||
cell.setModel(with: element) |
|||
} |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.selectedHistory |
|||
.drive(onNext: { |
|||
guard let model = $0 else { return } |
|||
|
|||
self.presentingViewController?.view.endEditing(true) |
|||
self.mainView.originToBottom { |
|||
self.dismiss(animated: true) { |
|||
self.delegate?.recentHistories(self, didSelectHistory: model) |
|||
} |
|||
} |
|||
}).disposed(by: disposeBag) |
|||
|
|||
output.showPeriodTrigger |
|||
.drive(onNext: { (from, to) in |
|||
|
|||
let originDateFormatter = DateFormatter() |
|||
originDateFormatter.dateFormat = "yyyy-MM-dd" |
|||
|
|||
let dateFormatter = DateFormatter() |
|||
dateFormatter.dateFormat = "MMM d, yyyy" |
|||
|
|||
guard |
|||
let startDate = from, |
|||
let endDate = to, |
|||
let changeFormatStartDate = originDateFormatter.date(from: startDate), |
|||
let changeFormatEndDate = originDateFormatter.date(from: endDate) |
|||
else { return } |
|||
|
|||
self.startDateLabel.text = dateFormatter.string(from: changeFormatStartDate) |
|||
self.endDateLabel.text = dateFormatter.string(from: changeFormatEndDate) |
|||
|
|||
self.setPeriodViewStatus(isHidden: false) |
|||
self.searchBar.text?.removeAll() |
|||
}).disposed(by: disposeBag) |
|||
|
|||
closeButton.rx.tap |
|||
.bind { |
|||
self.presentingViewController?.view.endEditing(true) |
|||
self.mainView.originToBottom { |
|||
self.dismiss(animated: true) |
|||
} |
|||
}.disposed(by: disposeBag) |
|||
} |
|||
|
|||
private func setPeriodViewStatus(isHidden: Bool) { |
|||
// periodView.isHidden = isHidden |
|||
periodViewHeightConstraint.constant = isHidden ? 0.0 : 35.0 |
|||
} |
|||
|
|||
} |
|||
|
|||
extension RecentHistoriesViewController: UITableViewDelegate { |
|||
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { |
|||
return 70 |
|||
} |
|||
|
|||
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { |
|||
view.endEditing(true) |
|||
} |
|||
} |
@ -1,104 +0,0 @@ |
|||
// |
|||
// RecentHistoriesViewModel.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import RxSwift |
|||
import RxCocoa |
|||
|
|||
class RecentHistoriesViewModel: ViewModelType { |
|||
var presenter: RecentHistoriesModuleInterface? |
|||
|
|||
struct Input { |
|||
let viewWillAppear: Driver<Void> |
|||
let filterText: Driver<String?> |
|||
let selectTrigger: Driver<IndexPath> |
|||
let calendarTrigger: Driver<Void> |
|||
let closeCalandarTrigger: Driver<Void> |
|||
} |
|||
|
|||
struct Output { |
|||
let isError: Driver<Error> |
|||
let isProgress: Driver<Bool> |
|||
let histories: Driver<[RecentRecipientModel]> |
|||
let selectedHistory: Driver<RecentRecipientModel?> |
|||
let showPeriodTrigger: Driver<(String?, String?)> |
|||
} |
|||
|
|||
private let disposeBag = DisposeBag() |
|||
|
|||
private let progressLinker = PublishSubject<Bool>() |
|||
private let errorLinker = PublishSubject<Error>() |
|||
|
|||
private let selectedHistoryLinker = BehaviorSubject<RecentRecipientModel?>(value: nil) |
|||
private let historiesLinker = BehaviorSubject<[RecentRecipientModel]>(value: []) |
|||
|
|||
func transform(input: Input) -> Output { |
|||
|
|||
let histories = Observable.combineLatest( |
|||
historiesLinker, input.filterText.asObservable() |
|||
) { histories, searchText -> [RecentRecipientModel] in |
|||
guard let searchText = searchText, searchText != "" else { |
|||
return histories |
|||
} |
|||
return histories.filter {( $0.name?.lowercased().contains(searchText.lowercased()) ?? false )} |
|||
}.asDriverOnErrorJustComplete() |
|||
|
|||
input.viewWillAppear |
|||
.drive(onNext: {self.presenter?.fetchHistories(from: "", to: "")}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
input.selectTrigger |
|||
.withLatestFrom(histories) { (indexPath, histories) -> RecentRecipientModel in |
|||
return histories[indexPath.row] |
|||
} |
|||
.drive(onNext: { [weak self] in guard let `self` = self else { return } |
|||
self.selectedHistoryLinker.onNext($0) |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
let showPeriodTrigger = PublishSubject<(String?, String?)>() |
|||
|
|||
input.calendarTrigger |
|||
.drive(onNext: { |
|||
self.presenter?.presentDatePicker { (from, to) in |
|||
showPeriodTrigger.onNext((from, to)) |
|||
self.presenter?.fetchHistories(from: from ?? "", to: to ?? "")} |
|||
} |
|||
) |
|||
.disposed(by: disposeBag) |
|||
|
|||
input.closeCalandarTrigger |
|||
.drive(onNext: { |
|||
self.presenter?.fetchHistories(from: "", to: "") |
|||
} |
|||
) |
|||
.disposed(by: disposeBag) |
|||
|
|||
return Output( |
|||
isError: errorLinker.asDriverOnErrorJustComplete(), |
|||
isProgress: progressLinker.asDriverOnErrorJustComplete(), |
|||
histories: histories, |
|||
selectedHistory: selectedHistoryLinker.asDriverOnErrorJustComplete(), |
|||
showPeriodTrigger: showPeriodTrigger.asDriverOnErrorJustComplete() |
|||
) |
|||
} |
|||
} |
|||
|
|||
// MARK: RecentHistories view interface |
|||
extension RecentHistoriesViewModel: RecentHistoriesViewModelInterface { |
|||
func setError(with error: Error) { |
|||
errorLinker.onNext(error) |
|||
} |
|||
|
|||
func progress(isShow: Bool) { |
|||
progressLinker.onNext(isShow) |
|||
} |
|||
|
|||
func setHistories(with model: [RecentRecipientModel]) { |
|||
historiesLinker.onNext(model) |
|||
} |
|||
} |
@ -1,14 +0,0 @@ |
|||
// |
|||
// RecentHistoriesViewModelInterface.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
protocol RecentHistoriesViewModelInterface: class { |
|||
func setError(with error: Error) |
|||
func progress(isShow: Bool) |
|||
|
|||
func setHistories(with model: [RecentRecipientModel]) |
|||
} |
@ -1,62 +0,0 @@ |
|||
// |
|||
// RecentHistoriesWireframe.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import UIKit |
|||
|
|||
class RecentHistoriesWireframe { |
|||
weak var view: UIViewController! |
|||
weak var output: RecentHistoriesWireframeOutput? |
|||
private weak var delegate: RecentHistoriesDelegate? |
|||
} |
|||
|
|||
extension RecentHistoriesWireframe: RecentHistoriesWireframeInput { |
|||
|
|||
var storyboardName: String {return "RecentHistories"} |
|||
|
|||
func getMainView() -> UIViewController { |
|||
let service = RecentHistoriesService() |
|||
let interactor = RecentHistoriesInteractor(service: service) |
|||
let presenter = RecentHistoriesPresenter() |
|||
let viewModel = RecentHistoriesViewModel() |
|||
let viewController = viewControllerFromStoryboard(of: RecentHistoriesViewController.self) |
|||
|
|||
output = presenter |
|||
|
|||
viewController.viewModel = viewModel |
|||
viewController.delegate = delegate |
|||
|
|||
interactor.output = presenter |
|||
presenter.interactor = interactor |
|||
presenter.wireframe = self |
|||
presenter.viewModel = viewModel |
|||
|
|||
viewModel.presenter = presenter |
|||
|
|||
view = viewController |
|||
return viewController |
|||
} |
|||
|
|||
func open(delegate: RecentHistoriesDelegate?, on source: UIViewController) { |
|||
self.delegate = delegate |
|||
let vc = getMainView() |
|||
|
|||
source.present(vc, animated: true, completion: nil) |
|||
} |
|||
|
|||
func presentDatePicker(completion: ((_ from: String?, _ to: String?) -> Void)?) { |
|||
guard let datePickerViewController = UIStoryboard |
|||
.init(name: "TransactionHistoryDatePicker", bundle: nil) |
|||
.instantiateViewController( |
|||
withIdentifier: "DatePickerViewController" |
|||
) as? DatePickerViewController else { return } |
|||
|
|||
datePickerViewController.completion = completion |
|||
|
|||
view.present(datePickerViewController, animated: true, completion: nil) |
|||
} |
|||
} |
@ -1,17 +0,0 @@ |
|||
// |
|||
// RecentHistoriesWireframeInputOutput.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 17/09/2019. |
|||
//Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
|
|||
protocol RecentHistoriesWireframeInput: WireframeInput { |
|||
func presentDatePicker(completion: ((_ from: String?, _ to: String?) -> Void)?) |
|||
} |
|||
|
|||
protocol RecentHistoriesWireframeOutput: class { |
|||
|
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue