InKwon James Kim
5 years ago
196 changed files with 2845 additions and 20 deletions
-
326GME Remit.xcodeproj/project.pbxproj
-
16GME Remit/Extensions/UIImageView+Ext.swift
-
11GME Remit/Extensions/UIView+Ext.swift
-
BINGME Remit/Modules/.DS_Store
-
11GME Remit/Modules/AutoDebitModules/AddAccount/Application Logic/Model/KFTCBankList.swift
-
19GME Remit/Modules/Home/User Interface/View/Cell/HomeCollectionTableViewCell.swift
-
4GME Remit/Modules/Home/User Interface/View/Home.storyboard
-
40GME Remit/Modules/Home/User Interface/View/HomeViewController.swift
-
10GME Remit/Modules/RecipientModules/Recipients/Application Logic/Model/Account/AccountModel.swift
-
2GME Remit/Modules/RecipientModules/Recipients/User Interface/View/RecipientsViewController.swift
-
2GME Remit/Modules/RecipientModules/SetupRecipient/User Interface/View/SetupRecipientViewController.swift
-
44GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Interactor/DomesticRemitInteractor.swift
-
18GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Interactor/DomesticRemitInteractorIO.swift
-
26GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Model/DomesticRemitModel.swift
-
23GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Model/RecipientNameModel.swift
-
188GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Service/DomesticRemitService.swift
-
21GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Application Logic/Service/DomesticRemitServiceType.swift
-
13GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/Module Interface/DomesticRemitModuleInterface.swift
-
75GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/Presenter/DomesticRemitPresenter.swift
-
491GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/View/DomesticRemit.storyboard
-
318GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/View/DomesticRemitViewController.swift
-
125GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/View/ViewModel/DomesticRemitViewModel.swift
-
16GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/View/ViewModel/DomesticRemitViewModelInterface.swift
-
89GME Remit/Modules/RemittanceModules/DomesticModules/DomesticRemit/User Interface/Wireframe/DomesticRemitWireframe.swift
-
18GME 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
-
73GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/Application Logic/Service/RecentHistoriesService.swift
-
16GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/Application Logic/Service/RecentHistoriesServiceType.swift
-
14GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/Module Interface/RecentHistoriesModuleInterface.swift
-
44GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/Presenter/RecentHistoriesPresenter.swift
-
21GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/View/Cell/RecentRecipientCell.swift
-
196GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/View/RecentHistories.storyboard
-
128GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/View/RecentHistoriesViewController.swift
-
82GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/View/ViewModel/RecentHistoriesViewModel.swift
-
14GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/View/ViewModel/RecentHistoriesViewModelInterface.swift
-
50GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/Wireframe/RecentHistoriesWireframe.swift
-
17GME Remit/Modules/RemittanceModules/DomesticModules/RecentHistories/User Interface/Wireframe/RecentHistoriesWireframeInputOutput.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/Application Logic/Interactor/PaymentSelectionInteractor.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/Application Logic/Interactor/PaymentSelectionInteractorIO.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/Application Logic/Service/PaymentSelectionService.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/Application Logic/Service/PaymentSelectionServiceType.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/Module Interface/PaymentSelectionModuleInterface.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/User Interface/Presenter/PaymentSelectionPresenter.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/User Interface/View/Cells/PaymentSelectionTableViewCell.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/User Interface/View/PaymentSelection.storyboard
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/User Interface/View/PaymentSelectionViewController.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/User Interface/View/PaymentSelectionViewInterface.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/User Interface/Wireframe/PaymentSelectionWireframe.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/PaymentSelection/User Interface/Wireframe/PaymentSelectionWireframeInput.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/Application Logic/Interactor/ResendInteractor.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/Application Logic/Interactor/ResendInteractorIO.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/Application Logic/Service/ResendService.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/Application Logic/Service/ResendServiceType.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/Module Interface/ResendModuleInterface.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/User Interface/Presenter/ResendPresenter.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/User Interface/View/Cell/ResendTableViewCell.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/User Interface/View/Resend.storyboard
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/User Interface/View/ResendViewController.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/User Interface/View/ResendViewInterface.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/User Interface/Wireframe/ResendWireframe.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/Resend/User Interface/Wireframe/ResendWireframeInput.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/ResendExchange/Application Logic/Interactor/ResendExchangeInteractor.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/ResendExchange/Application Logic/Interactor/ResendExchangeInteractorIO.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/ResendExchange/Application Logic/Service/ResendExchangeService.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/ResendExchange/Application Logic/Service/ResendExchangeServiceType.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/ResendExchange/Module Interface/ResendExchangeModuleInterface.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/ResendExchange/User Interface/Presenter/ResendExchangePresenter.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/ResendExchange/User Interface/View/ResendExchange.storyboard
-
0GME Remit/Modules/RemittanceModules/OverseasModules/ResendExchange/User Interface/View/ResendExchangeViewController.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/ResendExchange/User Interface/View/ResendExchangeViewInterface.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/ResendExchange/User Interface/Wireframe/ResendExchangeWireframe.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/ResendExchange/User Interface/Wireframe/ResendExchangeWireframeInput.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/Application Logic/Interactor/SelectCouponInteractor.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/Application Logic/Interactor/SelectCouponInteractorIO.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/Application Logic/Service/SelectCouponService.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/Application Logic/Service/SelectCouponServiceType.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/Module Interface/SelectCouponModuleInterface.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/User Interface/Presenter/SelectCouponPresenter.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/User Interface/View/Cell/CouponCell.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/User Interface/View/SelectCoupon.storyboard
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/User Interface/View/SelectCouponViewController.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/User Interface/View/SelectCouponViewInterface.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/User Interface/Wireframe/SelectCouponWireframe.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectCoupon/User Interface/Wireframe/SelectCouponWireframeInput.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/Application Logic/Interactor/SelectPaymentInteractor.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/Application Logic/Interactor/SelectPaymentInteractorIO.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/Application Logic/Service/SelectPaymentService.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/Application Logic/Service/SelectPaymentServiceType.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/Module Interface/SelectPaymentModuleInterface.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/User Interface/Presenter/SelectPaymentPresenter.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/User Interface/View/Cell/PaymentCell.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/User Interface/View/SelectPayment.storyboard
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/User Interface/View/SelectPaymentViewController.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/User Interface/View/SelectPaymentViewInterface.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/User Interface/Wireframe/SelectPaymentWireframe.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SelectPayment/User Interface/Wireframe/SelectPaymentWireframeInput.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SendMoneyCode/Application Logic/Interactor/SendMoneyCodeInteractor.swift
-
0GME Remit/Modules/RemittanceModules/OverseasModules/SendMoneyCode/Application Logic/Interactor/SendMoneyCodeInteractorIO.swift
@ -0,0 +1,16 @@ |
|||
// |
|||
// UIImageView+Ext.swift |
|||
// GME Remit |
|||
// |
|||
// Created by InKwon James Kim on 18/09/2019. |
|||
// Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. |
|||
// |
|||
|
|||
import UIKit |
|||
|
|||
extension UIImageView { |
|||
func setDropDownImage(tintColor: UIColor){ |
|||
self.image = #imageLiteral(resourceName: "dropdown_white").withRenderingMode(UIImage.RenderingMode.alwaysTemplate) |
|||
self.tintColor = tintColor |
|||
} |
|||
} |
@ -0,0 +1,44 @@ |
|||
// |
|||
// 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)} |
|||
) |
|||
} |
|||
} |
@ -0,0 +1,18 @@ |
|||
// |
|||
// 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) |
|||
} |
|||
|
|||
protocol DomesticRemitInteractorOutput: class { |
|||
func setModel(with model: DomesticRemitModel) |
|||
func setRecipientName(with model: RecipientNameModel) |
|||
func setError(with error: Error) |
|||
} |
@ -0,0 +1,26 @@ |
|||
// |
|||
// 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? |
|||
|
|||
init?(map: Map) { |
|||
|
|||
} |
|||
|
|||
mutating func mapping(map: Map) { |
|||
accounts <- map["accounts"] |
|||
banks <- map["banks"] |
|||
serviceFee <- map["serviceFee"] |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
// |
|||
// 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"] |
|||
} |
|||
} |
@ -0,0 +1,188 @@ |
|||
// |
|||
// 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 |
|||
) { |
|||
// FIXME: Test Model |
|||
let testModel = |
|||
""" |
|||
{ |
|||
"accounts" : [ |
|||
{ |
|||
"BankCode" : null, |
|||
"UserCi" : null, |
|||
"AccountNum" : null, |
|||
"BankName" : "신한은행", |
|||
"WalletName" : null, |
|||
"AutoDebit" : null, |
|||
"Type" : null, |
|||
"FintechUseNo" : null, |
|||
"AccountNumMasked" : "110223458***", |
|||
"FullAccountName" : null, |
|||
"IsApproved" : null, |
|||
"AccHolderInfoType" : null, |
|||
"Scope" : null, |
|||
"UserSeqNo" : null, |
|||
"KftcAccountId" : "IUgUkVvizgTGwzYtJ+qIZw==", |
|||
"CustomerId" : null, |
|||
"BankCodeStd" : null, |
|||
"IsShowRefresh" : "N", |
|||
"AccessToken" : null, |
|||
"AccHolderInfo" : null, |
|||
"AccountName" : null, |
|||
"TokenType" : null |
|||
}, |
|||
{ |
|||
"BankCode" : null, |
|||
"UserCi" : null, |
|||
"AccountNum" : null, |
|||
"BankName" : "KB국민은행", |
|||
"WalletName" : null, |
|||
"AutoDebit" : null, |
|||
"Type" : null, |
|||
"FintechUseNo" : null, |
|||
"AccountNumMasked" : "40790204056***", |
|||
"FullAccountName" : null, |
|||
"IsApproved" : null, |
|||
"AccHolderInfoType" : null, |
|||
"Scope" : null, |
|||
"UserSeqNo" : null, |
|||
"KftcAccountId" : "zy5wvuekamf9soEMhw5trA==", |
|||
"CustomerId" : null, |
|||
"BankCodeStd" : null, |
|||
"IsShowRefresh" : "N", |
|||
"AccessToken" : null, |
|||
"AccHolderInfo" : null, |
|||
"AccountName" : null, |
|||
"TokenType" : null |
|||
} |
|||
], |
|||
|
|||
"banks" : [ |
|||
{ |
|||
"RowId" : "7", |
|||
"BankName" : "Korea Development Bank(KDB)", |
|||
"BankCode" : "002" |
|||
}, |
|||
{ |
|||
"RowId" : "3", |
|||
"BankName" : "Industrial Bank of Korea(IBK)", |
|||
"BankCode" : "003" |
|||
}, |
|||
{ |
|||
"RowId" : "2", |
|||
"BankName" : "Kookmin-Bank(KB)", |
|||
"BankCode" : "004" |
|||
}, |
|||
{ |
|||
"RowId" : "9", |
|||
"BankName" : "Suhyup Local Cooperatives", |
|||
"BankCode" : "007" |
|||
}, |
|||
{ |
|||
"RowId" : "4", |
|||
"BankName" : "Nonghyup Bank(NH)", |
|||
"BankCode" : "011" |
|||
}, |
|||
{ |
|||
"RowId" : "21", |
|||
"BankName" : "Woori Bank", |
|||
"BankCode" : "020" |
|||
}, |
|||
{ |
|||
"RowId" : "16", |
|||
"BankName" : "Standard Chartered Korea(SC First)", |
|||
"BankCode" : "023" |
|||
}, |
|||
{ |
|||
"RowId" : "18", |
|||
"BankName" : "Citibank Korea", |
|||
"BankCode" : "027" |
|||
}, |
|||
{ |
|||
"RowId" : "5", |
|||
"BankName" : "Daegu Bank(DGB)", |
|||
"BankCode" : "031" |
|||
}, |
|||
{ |
|||
"RowId" : "20", |
|||
"BankName" : "Busan Bank(BNK)", |
|||
"BankCode" : "032" |
|||
}, |
|||
{ |
|||
"RowId" : "1", |
|||
"BankName" : "Kwangju Bank(KJ)", |
|||
"BankCode" : "034" |
|||
}, |
|||
{ |
|||
"RowId" : "17", |
|||
"BankName" : "Jeju Bank", |
|||
"BankCode" : "035" |
|||
}, |
|||
{ |
|||
"RowId" : "15", |
|||
"BankName" : "Jeonbuk Bank(JB)", |
|||
"BankCode" : "037" |
|||
}, |
|||
{ |
|||
"RowId" : "25", |
|||
"BankName" : "Kyongnam Bank", |
|||
"BankCode" : "039" |
|||
}, |
|||
{ |
|||
"RowId" : "13", |
|||
"BankName" : "KEB Hana Bank", |
|||
"BankCode" : "081" |
|||
}, |
|||
{ |
|||
"RowId" : "10", |
|||
"BankName" : "Shinhan Bank", |
|||
"BankCode" : "088" |
|||
} |
|||
], |
|||
|
|||
"serviceFee": "1500" |
|||
} |
|||
""" |
|||
|
|||
guard let json = DomesticRemitModel(JSONString: testModel) else { return } |
|||
success(json) |
|||
} |
|||
|
|||
func getRecipientName( |
|||
account: String, |
|||
bankCode: String, |
|||
success: @escaping (RecipientNameModel) -> Void, |
|||
failure: @escaping (Error) -> Void |
|||
) { |
|||
let testModel = |
|||
""" |
|||
{ |
|||
"ErrorCode": "0", |
|||
"Msg": "Success", |
|||
"Id": null, |
|||
"Extra": "", |
|||
"Extra2": "", |
|||
"Data": { |
|||
"RecipientName": "James", |
|||
"RecipientPhone": "01052850125" |
|||
} |
|||
} |
|||
""" |
|||
|
|||
guard |
|||
let json = ResponseContainerObject<RecipientNameModel>(JSONString: testModel), |
|||
let data = json.data else { return } |
|||
success(data) |
|||
} |
|||
} |
@ -0,0 +1,21 @@ |
|||
// |
|||
// 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 |
|||
) |
|||
} |
@ -0,0 +1,13 @@ |
|||
// |
|||
// 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) |
|||
} |
@ -0,0 +1,75 @@ |
|||
// |
|||
// 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]? |
|||
|
|||
enum ShowType: Int { |
|||
case histories = 0 |
|||
case banks |
|||
case autodebit |
|||
} |
|||
} |
|||
|
|||
// MARK: DomesticRemit module interface |
|||
extension DomesticRemitPresenter: DomesticRemitModuleInterface { |
|||
func fetchInformation() { |
|||
interactor?.fetchInformation() |
|||
} |
|||
|
|||
func showTablePresenter(type: ShowType) { |
|||
switch type { |
|||
case .histories: |
|||
wireframe?.showRecentHistories() |
|||
|
|||
case .banks: |
|||
wireframe?.showTablePresenter(with: banks, type: type) |
|||
|
|||
case .autodebit: |
|||
wireframe?.showTablePresenter(with: accounts, type: type) |
|||
} |
|||
} |
|||
|
|||
func getRecipientName(account: String, bankCode: String) { |
|||
interactor?.getRecipientName(account: account, bankCode: bankCode) |
|||
} |
|||
} |
|||
|
|||
// MARK: DomesticRemit interactor output interface |
|||
extension DomesticRemitPresenter: DomesticRemitInteractorOutput { |
|||
func setModel(with model: DomesticRemitModel) { |
|||
banks = model.banks |
|||
accounts = model.accounts |
|||
|
|||
viewModel?.setModel(with: model) |
|||
} |
|||
|
|||
func setRecipientName(with model: RecipientNameModel) { |
|||
viewModel?.setRecipientName(with: model) |
|||
} |
|||
|
|||
func setError(with error: Error) { |
|||
viewModel?.setError(with: error) |
|||
} |
|||
} |
|||
|
|||
// MARK: DomesticRemit wireframe output interface |
|||
extension DomesticRemitPresenter: DomesticRemitWireframeOutput { |
|||
func selectedData(with model: TablePresenterProtocol?, type: ShowType) { |
|||
viewModel?.selectedData(with: model, type: type) |
|||
} |
|||
} |
@ -0,0 +1,491 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Sd9-9A-f1x"> |
|||
<device id="retina4_7" orientation="portrait"> |
|||
<adaptation id="fullscreen"/> |
|||
</device> |
|||
<dependencies> |
|||
<deployment identifier="iOS"/> |
|||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/> |
|||
<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="1000"/> |
|||
<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="1000"/> |
|||
<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="726"/> |
|||
<subviews> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0TS-Id-072"> |
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="150"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="NIp-JO-z9g"> |
|||
<rect key="frame" x="20" y="20" width="335" height="110"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gPj-g8-2ov"> |
|||
<rect key="frame" x="0.0" y="0.0" 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="255" 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> |
|||
<nil key="textColor"/> |
|||
<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="255" 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"/> |
|||
<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> |
|||
</view> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eOv-y4-ViC"> |
|||
<rect key="frame" x="285" y="0.0" width="50" height="50"/> |
|||
<constraints> |
|||
<constraint firstAttribute="width" constant="50" id="EvG-UU-HiC"/> |
|||
</constraints> |
|||
<fontDescription key="fontDescription" type="system" pointSize="17"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
</stackView> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zoq-Ph-ipO"> |
|||
<rect key="frame" x="0.0" y="60" width="335" height="50"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pJB-eJ-bWJ"> |
|||
<rect key="frame" x="128.5" y="0.0" width="78.5" height="50"/> |
|||
<subviews> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" 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="28.5" height="50"/> |
|||
<fontDescription key="fontDescription" type="system" pointSize="17"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="(KRW)" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JOx-My-xUB"> |
|||
<rect key="frame" x="28.5" y="0.0" width="50" height="50"/> |
|||
<constraints> |
|||
<constraint firstAttribute="width" constant="50" id="3Z6-tp-ZQk"/> |
|||
</constraints> |
|||
<fontDescription key="fontDescription" type="system" pointSize="17"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
</stackView> |
|||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FST-pR-26v"> |
|||
<rect key="frame" x="217" y="0.0" width="50" height="50"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="Zer-sU-Nul"/> |
|||
<constraint firstAttribute="width" secondItem="FST-pR-26v" secondAttribute="height" multiplier="1:1" id="dm6-TC-USy"/> |
|||
</constraints> |
|||
<color key="tintColor" red="0.92941176469999998" green="0.1137254902" blue="0.1960784314" alpha="1" colorSpace="calibratedRGB"/> |
|||
<state key="normal" image="refresh"/> |
|||
</button> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="pJB-eJ-bWJ" firstAttribute="centerY" secondItem="Zoq-Ph-ipO" secondAttribute="centerY" id="6tL-hR-pIv"/> |
|||
<constraint firstItem="pJB-eJ-bWJ" firstAttribute="top" secondItem="Zoq-Ph-ipO" secondAttribute="top" id="9RI-TG-bPS"/> |
|||
<constraint firstItem="pJB-eJ-bWJ" firstAttribute="centerX" secondItem="Zoq-Ph-ipO" secondAttribute="centerX" id="cKf-rQ-gdO"/> |
|||
<constraint firstAttribute="bottom" secondItem="FST-pR-26v" secondAttribute="bottom" id="gf1-4Y-OJY"/> |
|||
<constraint firstItem="FST-pR-26v" firstAttribute="top" secondItem="Zoq-Ph-ipO" secondAttribute="top" id="qrF-Ot-isr"/> |
|||
<constraint firstAttribute="bottom" secondItem="pJB-eJ-bWJ" secondAttribute="bottom" id="xRn-NY-zgy"/> |
|||
<constraint firstItem="FST-pR-26v" firstAttribute="leading" secondItem="pJB-eJ-bWJ" secondAttribute="trailing" constant="10" id="zcQ-O2-b2r"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
</stackView> |
|||
</subviews> |
|||
<color key="backgroundColor" red="0.93333333333333335" green="0.93333333333333335" blue="0.93333333333333335" alpha="1" colorSpace="calibratedRGB"/> |
|||
<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="20" id="rAH-II-bAa"/> |
|||
</constraints> |
|||
</view> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="me5-tr-dab"> |
|||
<rect key="frame" x="10" y="150.5" width="355" height="565.5"/> |
|||
<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="545.5"/> |
|||
<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" red="0.2901960784" green="0.2901960784" blue="0.2901960784" alpha="1" colorSpace="calibratedRGB"/> |
|||
<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="475.5"/> |
|||
<subviews> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="o37-sL-MaJ"> |
|||
<rect key="frame" x="0.0" y="0.0" width="335" height="115"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="TF3-ZE-jcy"> |
|||
<rect key="frame" x="10" y="0.0" width="315" height="115"/> |
|||
<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" red="0.2901960784" green="0.2901960784" blue="0.2901960784" alpha="1" colorSpace="calibratedRGB"/> |
|||
<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 Korea Bank"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="YES"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/> |
|||
</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"/> |
|||
<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="1" alpha="1" 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="1" alpha="1" 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" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<state key="normal" image="ic_review"/> |
|||
</button> |
|||
</subviews> |
|||
<color key="backgroundColor" white="1" alpha="1" 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="65" width="315" height="50"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="Rda-Uz-UNf"/> |
|||
</constraints> |
|||
<color key="textColor" red="0.2901960784" green="0.2901960784" blue="0.2901960784" alpha="1" colorSpace="calibratedRGB"/> |
|||
<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> |
|||
</subviews> |
|||
</stackView> |
|||
</subviews> |
|||
<color key="backgroundColor" white="1" alpha="1" 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> |
|||
<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="135" width="335" 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-Regular" family="San Francisco Display" pointSize="17"/> |
|||
<state key="normal" title="Ok"> |
|||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
</state> |
|||
</button> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sDV-rn-swX"> |
|||
<rect key="frame" x="0.0" y="205" width="335" height="200.5"/> |
|||
<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="200.5"/> |
|||
<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"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="9Vo-Te-ee3"/> |
|||
</constraints> |
|||
<color key="textColor" red="0.2901960784" green="0.2901960784" blue="0.2901960784" alpha="1" colorSpace="calibratedRGB"/> |
|||
<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"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="Ea4-uA-N7E"/> |
|||
</constraints> |
|||
<color key="textColor" red="0.2901960784" green="0.2901960784" blue="0.2901960784" alpha="1" colorSpace="calibratedRGB"/> |
|||
<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="9QG-ay-o3w"> |
|||
<rect key="frame" x="0.0" y="130" width="315" height="70.5"/> |
|||
<subviews> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cbp-DC-HyK"> |
|||
<rect key="frame" x="-30" y="0.0" width="375" height="0.5"/> |
|||
<color key="backgroundColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="0.5" id="ajh-OG-NBT"/> |
|||
</constraints> |
|||
</view> |
|||
<textField opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Service Fee" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="xGB-im-tHp" customClass="ValidationTextField" customModule="GME_Remit" customModuleProvider="target"> |
|||
<rect key="frame" x="0.0" y="20.5" width="315" height="50"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="50" id="KoJ-Zu-TAj"/> |
|||
</constraints> |
|||
<color key="textColor" red="0.2901960784" green="0.2901960784" blue="0.2901960784" alpha="1" colorSpace="calibratedRGB"/> |
|||
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="17"/> |
|||
<textInputTraits key="textInputTraits"/> |
|||
<userDefinedRuntimeAttributes> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="titleText" value="Service Fee"/> |
|||
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Service Fee"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="YES"/> |
|||
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="YES"/> |
|||
</userDefinedRuntimeAttributes> |
|||
</textField> |
|||
</subviews> |
|||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="trailing" secondItem="cbp-DC-HyK" secondAttribute="trailing" constant="-30" id="3OF-oK-qOX"/> |
|||
<constraint firstItem="xGB-im-tHp" firstAttribute="top" secondItem="cbp-DC-HyK" secondAttribute="bottom" constant="20" id="D9R-eL-k5j"/> |
|||
<constraint firstItem="cbp-DC-HyK" firstAttribute="top" secondItem="9QG-ay-o3w" secondAttribute="top" id="MOK-tg-b4Z"/> |
|||
<constraint firstAttribute="bottom" secondItem="xGB-im-tHp" secondAttribute="bottom" id="NYo-5J-nRD"/> |
|||
<constraint firstAttribute="trailing" secondItem="xGB-im-tHp" secondAttribute="trailing" id="NgK-aC-g3J"/> |
|||
<constraint firstItem="xGB-im-tHp" firstAttribute="leading" secondItem="9QG-ay-o3w" secondAttribute="leading" id="UXs-e0-gfC"/> |
|||
<constraint firstItem="cbp-DC-HyK" firstAttribute="leading" secondItem="9QG-ay-o3w" secondAttribute="leading" constant="-30" id="dD3-Vv-RtT"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
</stackView> |
|||
</subviews> |
|||
<color key="backgroundColor" white="1" alpha="1" 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> |
|||
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="UYi-o5-Inc"> |
|||
<rect key="frame" x="0.0" y="425.5" width="335" 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-Regular" family="San Francisco Display" pointSize="17"/> |
|||
<state key="normal" title="Send"> |
|||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
</state> |
|||
</button> |
|||
</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="150" width="375" height="0.5"/> |
|||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstAttribute="height" constant="0.5" id="en2-Cw-FD0"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> |
|||
<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" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<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="Domestic Remittance" id="Osp-Sl-e7G"/> |
|||
<size key="freeformSize" width="375" height="1000"/> |
|||
<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="balanceButton" destination="FST-pR-26v" id="fjO-x9-VAl"/> |
|||
<outlet property="balanceContainerView" destination="Zoq-Ph-ipO" id="aRk-rf-pM4"/> |
|||
<outlet property="balanceLabel" destination="crF-eg-HNv" id="u6O-Xb-WhA"/> |
|||
<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="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="sendButton" destination="UYi-o5-Inc" id="OAE-Q6-Otp"/> |
|||
<outlet property="serviceFeeTextField" destination="xGB-im-tHp" id="nzH-kp-t0n"/> |
|||
</connections> |
|||
</viewController> |
|||
<placeholder placeholderIdentifier="IBFirstResponder" id="8je-5K-XuW" userLabel="First Responder" sceneMemberID="firstResponder"/> |
|||
<tapGestureRecognizer id="UO0-lt-tVC"/> |
|||
</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="20" 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> |
|||
<resources> |
|||
<image name="ic_review" width="28" height="39"/> |
|||
<image name="refresh" width="40" height="40"/> |
|||
</resources> |
|||
<color key="tintColor" red="0.78177064659999995" green="0.55228364470000002" blue="0.018981300289999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> |
|||
</document> |
@ -0,0 +1,318 @@ |
|||
// |
|||
// 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! |
|||
|
|||
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 serviceFeeTextField: ValidationTextField! |
|||
@IBOutlet private weak var autoDebitTextField: ValidationTextField! |
|||
|
|||
@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 autodebitAccountDropDownImageView: UIImageView! |
|||
@IBOutlet private weak var balanceContainerView: UIView! |
|||
@IBOutlet private weak var bankDropDownImageView: UIImageView! |
|||
@IBOutlet private var bankDropDownTap: UITapGestureRecognizer! |
|||
|
|||
// MARK: VC's Life cycle |
|||
override func viewDidLoad() { |
|||
super.viewDidLoad() |
|||
setup() |
|||
} |
|||
|
|||
override func viewDidAppear(_ animated: Bool) { |
|||
super.viewDidAppear(animated) |
|||
} |
|||
|
|||
override func viewWillDisappear(_ animated: Bool) { |
|||
super.viewWillDisappear(animated) |
|||
|
|||
view.endEditing(true) |
|||
} |
|||
// MARK: IBActions |
|||
|
|||
} |
|||
|
|||
// MARK: Other Functions |
|||
extension DomesticRemitViewController { |
|||
private func setup() { |
|||
// all setup should be done here |
|||
setBinding() |
|||
setUI() |
|||
|
|||
setupNormalNavigation() |
|||
} |
|||
|
|||
private func setUI() { |
|||
mainContainerView.isHidden = true |
|||
balanceContainerView.isHidden = true |
|||
detailContainerView.isHidden = true |
|||
recipientInContainerView.isHidden = true |
|||
sendButton.layer.cornerRadius = 5 |
|||
|
|||
getNameButton.layer.cornerRadius = 5 |
|||
|
|||
recentHistoryButton.layer.cornerRadius = 5 |
|||
// recentHistoryButton.backgroundColor = .themeBlue |
|||
|
|||
bankTextField.inputView = UIView() |
|||
bankTextField.keyboardToolbar.isHidden = true |
|||
|
|||
autoDebitTextField.inputView = UIView() |
|||
autoDebitTextField.keyboardToolbar.isHidden = true |
|||
|
|||
bankDropDownImageView.setDropDownImage(tintColor: .themeTextColor) |
|||
autodebitAccountDropDownImageView.setDropDownImage(tintColor: .themeTextColor) |
|||
|
|||
recipientNameTextField.validCondition = {!$0.isEmpty} |
|||
recipientNameTextField.errorMessage = nil |
|||
|
|||
bankTextField.validCondition = {!$0.isEmpty} |
|||
bankTextField.errorMessage = nil |
|||
|
|||
autoDebitTextField.validCondition = {!$0.isEmpty} |
|||
autoDebitTextField.errorMessage = nil |
|||
|
|||
accountTextField.validCondition = {!$0.isEmpty && $0.count > 9} |
|||
accountTextField.errorMessage = "Invalid bank account number" |
|||
} |
|||
|
|||
private func setBinding() { |
|||
let viewWillAppear = rx.sentMessage(#selector(UIViewController.viewWillAppear(_:))) |
|||
.mapToVoid() |
|||
.asDriverOnErrorJustComplete() |
|||
|
|||
let input = DomesticRemitViewModel.Input( |
|||
viewWillAppear: viewWillAppear, |
|||
showRecentHistoryTrigger: recentHistoryButton.rx.tap.asDriver(), |
|||
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() |
|||
) |
|||
|
|||
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.map { "\($0?.serviceFee?.likeCommaMoney() ?? "") KRW" } |
|||
.drive(serviceFeeTextField.rx.text) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.selectedAutodebit |
|||
.drive(onNext: { |
|||
guard |
|||
let name = $0?.bankName, |
|||
let account = $0?.accountNumMasked else { return } |
|||
|
|||
self.autoDebitTextField.text = "\(name) (\(account))" |
|||
|
|||
self.balanceContainerView.animateHidden(isHidden: false) |
|||
self.mainContainerView.animateHidden(isHidden: false) |
|||
}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
output.selectedBank |
|||
.drive(onNext: { |
|||
self.recipientInContainerView.animateHidden(isHidden: true) |
|||
|
|||
self.bankTextField.text = $0?.bankName |
|||
self.bankTextField.setBank(with: $0?.bankCode, isShowCode: false) |
|||
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 } |
|||
|
|||
self.alertWithOkCancel( |
|||
type: .normal, |
|||
message: "Is the person who receives the remittance the name \(model.name ?? "nil")", |
|||
okTitle: "Ok", |
|||
cancelTitle: "No", |
|||
okAction: { |
|||
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) |
|||
} 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) |
|||
|
|||
// amount |
|||
amountTextField.rx.controlEvent(.editingChanged) |
|||
.subscribe(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() |
|||
.drive(onNext: { |
|||
guard let amount = self.amountTextField.text else { |
|||
return |
|||
} |
|||
|
|||
if amount != "" { |
|||
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) |
|||
|
|||
// 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) |
|||
|
|||
// 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 |
|||
} |
|||
.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) |
|||
} |
|||
} |
@ -0,0 +1,125 @@ |
|||
// |
|||
// 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 showRecentHistoryTrigger: Driver<Void> |
|||
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> |
|||
} |
|||
|
|||
struct Output { |
|||
let isError: Driver<Error> |
|||
let isProgress: Driver<Bool> |
|||
let selectedAutodebit: Driver<Account?> |
|||
let selectedBank: Driver<BankInformation?> |
|||
let selectedRecipient: Driver<RecentRecipientModel?> |
|||
let getRecipientName: Driver<RecipientNameModel?> |
|||
let getInitialData: Driver<DomesticRemitModel?> |
|||
} |
|||
|
|||
private let disposeBag = DisposeBag() |
|||
|
|||
private let progressLinker = PublishSubject<Bool>() |
|||
private let errorLinker = PublishSubject<Error>() |
|||
|
|||
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) |
|||
|
|||
func transform(input: Input) -> Output { |
|||
|
|||
input.viewWillAppear.drive(onNext: {self.presenter?.fetchInformation()}) |
|||
.disposed(by: disposeBag) |
|||
|
|||
input.selectAutodebit.drive(onNext: {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) |
|||
|
|||
return Output( |
|||
isError: errorLinker.asDriverOnErrorJustComplete(), |
|||
isProgress: progressLinker.asDriverOnErrorJustComplete(), |
|||
selectedAutodebit: selectedAutodebitLinker.asDriverOnErrorJustComplete(), |
|||
selectedBank: selectedBankLinker.asDriverOnErrorJustComplete(), |
|||
selectedRecipient: selectedHistoryLinker.asDriverOnErrorJustComplete(), |
|||
getRecipientName: getRecipientNameLinker.asDriverOnErrorJustComplete(), |
|||
getInitialData: getInitialDataLinker.asDriverOnErrorJustComplete() |
|||
) |
|||
} |
|||
} |
|||
|
|||
// 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) |
|||
} |
|||
|
|||
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) |
|||
|
|||
} |
|||
} |
|||
|
|||
func setRecipientName(with model: RecipientNameModel) { |
|||
getRecipientNameLinker.onNext(model) |
|||
} |
|||
} |
@ -0,0 +1,16 @@ |
|||
// |
|||
// 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) |
|||
} |
@ -0,0 +1,89 @@ |
|||
// |
|||
// 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? |
|||
} |
|||
|
|||
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 showRecentHistories() { |
|||
RecentHistoriesWireframe().open(delegate: self, on: view) |
|||
} |
|||
} |
|||
|
|||
extension DomesticRemitWireframe: TablePresenterDelegate { |
|||
func tablePresenterView(_ viewController: TablePresenterViewController) -> TablePresenterConfiguration { |
|||
return TablePresenterConfiguration( |
|||
presenterTitle: "Select Bank", |
|||
closeButtonTitle: "Close", |
|||
notFoundTitle: "Not Found", |
|||
searchBarPlaceHolder: "Search", |
|||
isUseSearchBar: false |
|||
) |
|||
} |
|||
|
|||
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) |
|||
} |
|||
} |
@ -0,0 +1,18 @@ |
|||
// |
|||
// 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 showRecentHistories() |
|||
} |
|||
|
|||
protocol DomesticRemitWireframeOutput: class { |
|||
func selectedData(with model: TablePresenterProtocol?, type: DomesticRemitPresenter.ShowType) |
|||
} |
@ -0,0 +1,40 @@ |
|||
// |
|||
// 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)} |
|||
) |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
// |
|||
// 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) |
|||
} |
@ -0,0 +1,35 @@ |
|||
// |
|||
// 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["RecipientAccount"] |
|||
name <- map["RecipientName"] |
|||
} |
|||
} |
|||
|
|||
extension RecentRecipientModel: TablePresenterProtocol { |
|||
var cellTitle: String? { |
|||
return name |
|||
} |
|||
|
|||
var cellImage: UIImage? { |
|||
return nil |
|||
} |
|||
} |
@ -0,0 +1,73 @@ |
|||
// |
|||
// 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.fetchRecentHistories( |
|||
// customerID: "", |
|||
// from: "", |
|||
// to: "" |
|||
// ) |
|||
|
|||
// FIXME: Test |
|||
|
|||
let test = """ |
|||
{ |
|||
"ErrorCode": "0", |
|||
"Msg": "Success", |
|||
"Id": null, |
|||
"Extra": "", |
|||
"Extra2": "", |
|||
"Data": [ |
|||
{ |
|||
"bank": { |
|||
"RowId" : "15", |
|||
"BankName" : "Shin", |
|||
"BankCode" : "037" |
|||
}, |
|||
|
|||
"RecipientAccount": "40790204056000", |
|||
"RecipientName": "James1" |
|||
}, |
|||
{ |
|||
"bank": { |
|||
"RowId" : "25", |
|||
"BankName" : "Kyongnam Bank", |
|||
"BankCode" : "039" |
|||
}, |
|||
|
|||
"RecipientAccount": "110223458044", |
|||
"RecipientName": "James3" |
|||
}, |
|||
{ |
|||
"bank": { |
|||
"RowId" : "13", |
|||
"BankName" : "KEB Hana Bank", |
|||
"BankCode" : "081" |
|||
}, |
|||
|
|||
"RecipientAccount": "12345678901", |
|||
"RecipientName": "James2" |
|||
} |
|||
] |
|||
} |
|||
""" |
|||
|
|||
let json = ResponseContainerArray<RecentRecipientModel>(JSONString: test) |
|||
|
|||
success(json?.data ?? []) |
|||
} |
|||
|
|||
} |
@ -0,0 +1,16 @@ |
|||
// |
|||
// 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 |
|||
) |
|||
} |
@ -0,0 +1,14 @@ |
|||
// |
|||
// 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 |
|||
) |
|||
} |
@ -0,0 +1,44 @@ |
|||
// |
|||
// 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 = "" |
|||
) { |
|||
interactor?.fetchHistories(from: from, to: to) |
|||
} |
|||
} |
|||
|
|||
// MARK: RecentHistories interactor output interface |
|||
extension RecentHistoriesPresenter: RecentHistoriesInteractorOutput { |
|||
func setHistories(with model: [RecentRecipientModel]) { |
|||
viewModel?.setHistories(with: model) |
|||
} |
|||
|
|||
func setError(with error: Error) { |
|||
viewModel?.setError(with: error) |
|||
} |
|||
} |
|||
|
|||
// MARK: RecentHistories wireframe output interface |
|||
extension RecentHistoriesPresenter: RecentHistoriesWireframeOutput { |
|||
|
|||
} |
@ -0,0 +1,21 @@ |
|||
// |
|||
// 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! |
|||
|
|||
func setModel(with model: RecentRecipientModel) { |
|||
nameLabel.text = model.name |
|||
accountLabel.text = model.account |
|||
bankLabel.text = model.bank?.bankName |
|||
} |
|||
} |
@ -0,0 +1,196 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="HSb-ou-7T5"> |
|||
<device id="retina4_7" orientation="portrait"> |
|||
<adaptation id="fullscreen"/> |
|||
</device> |
|||
<dependencies> |
|||
<deployment identifier="iOS"/> |
|||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/> |
|||
<capability name="Safe area layout guides" minToolsVersion="9.0"/> |
|||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> |
|||
</dependencies> |
|||
<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="133.5" width="375" height="533.5"/> |
|||
<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" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<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="119" y="11.5" width="137.5" height="20.5"/> |
|||
<fontDescription key="fontDescription" type="system" pointSize="17"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="EPv-JI-308" firstAttribute="leading" secondItem="Xuy-dc-FlA" secondAttribute="leading" id="3bL-5Z-mNf"/> |
|||
<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> |
|||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="vSd-Cn-NtH"> |
|||
<rect key="frame" x="0.0" y="94" width="375" height="439.5"/> |
|||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<view key="tableFooterView" contentMode="scaleToFill" id="Jc0-AE-AKV"> |
|||
<rect key="frame" x="0.0" y="98" width="375" 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="375" height="44"/> |
|||
<fontDescription key="fontDescription" type="system" pointSize="17"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
<color key="backgroundColor" white="1" alpha="1" 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="blue" 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="375" height="70"/> |
|||
<autoresizingMask key="autoresizingMask"/> |
|||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" ambiguous="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="X2M-ta-xHv" id="et9-GJ-ooJ"> |
|||
<rect key="frame" x="0.0" y="0.0" width="375" height="69.5"/> |
|||
<autoresizingMask key="autoresizingMask"/> |
|||
<subviews> |
|||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FkF-ac-dcc"> |
|||
<rect key="frame" x="10" y="10" width="355" height="45"/> |
|||
<subviews> |
|||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="4lw-Z7-vab"> |
|||
<rect key="frame" x="5" y="0.0" width="345" height="45"/> |
|||
<subviews> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="James Kim" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="ilt-ZQ-e17"> |
|||
<rect key="frame" x="0.0" y="13.5" width="111.5" height="17.5"/> |
|||
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="15"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Korea Development Bank(KDB)" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="9NA-kr-brd"> |
|||
<rect key="frame" x="116.5" y="5" width="112" height="35"/> |
|||
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="15"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="110223458044" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="sSB-S3-hHb"> |
|||
<rect key="frame" x="233.5" y="13.5" width="111.5" height="17.5"/> |
|||
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="15"/> |
|||
<nil key="textColor"/> |
|||
<nil key="highlightedColor"/> |
|||
</label> |
|||
</subviews> |
|||
</stackView> |
|||
</subviews> |
|||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="4lw-Z7-vab" firstAttribute="leading" secondItem="FkF-ac-dcc" secondAttribute="leading" constant="5" id="8HL-J5-Wqa"/> |
|||
<constraint firstAttribute="trailing" secondItem="4lw-Z7-vab" secondAttribute="trailing" constant="5" id="9zs-y8-CKC"/> |
|||
<constraint firstAttribute="height" constant="45" id="Btr-jU-qPi"/> |
|||
<constraint firstAttribute="bottom" secondItem="4lw-Z7-vab" secondAttribute="bottom" id="Pwj-Nc-aar"/> |
|||
<constraint firstItem="4lw-Z7-vab" firstAttribute="top" secondItem="FkF-ac-dcc" secondAttribute="top" id="vO4-Ae-DCb"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
<constraints> |
|||
<constraint firstAttribute="trailing" secondItem="FkF-ac-dcc" secondAttribute="trailing" constant="10" id="TSh-jG-UJ1"/> |
|||
<constraint firstItem="FkF-ac-dcc" firstAttribute="leading" secondItem="et9-GJ-ooJ" secondAttribute="leading" constant="10" 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> |
|||
<connections> |
|||
<outlet property="accountLabel" destination="sSB-S3-hHb" id="HfU-EG-pNP"/> |
|||
<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> |
|||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ean-iy-xy9"> |
|||
<rect key="frame" x="0.0" y="44" width="375" 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="325" 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="325" 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> |
|||
</subviews> |
|||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="vSd-Cn-NtH" firstAttribute="top" secondItem="Ean-iy-xy9" secondAttribute="bottom" id="1Xb-19-Pex"/> |
|||
<constraint firstItem="vSd-Cn-NtH" firstAttribute="leading" secondItem="9jL-Y3-Li7" secondAttribute="leading" id="4e9-7p-1hF"/> |
|||
<constraint firstAttribute="bottom" secondItem="vSd-Cn-NtH" secondAttribute="bottom" 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="vSd-Cn-NtH" secondAttribute="trailing" id="Aps-rw-KLW"/> |
|||
<constraint firstItem="Ean-iy-xy9" firstAttribute="leading" secondItem="9jL-Y3-Li7" secondAttribute="leading" 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" id="adi-8C-sFa"/> |
|||
<constraint firstItem="Xuy-dc-FlA" firstAttribute="leading" secondItem="9jL-Y3-Li7" secondAttribute="leading" id="qbJ-S8-MQa"/> |
|||
</constraints> |
|||
</view> |
|||
</subviews> |
|||
<color key="backgroundColor" white="0.0" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> |
|||
<constraints> |
|||
<constraint firstItem="9jL-Y3-Li7" firstAttribute="height" secondItem="9Uc-9s-KgO" secondAttribute="height" multiplier="0.8: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="mainView" destination="9jL-Y3-Li7" id="rU2-JH-1ys"/> |
|||
<outlet property="notFoundLabel" destination="DSX-pB-voq" id="RA9-u9-XWm"/> |
|||
<outlet property="searchBar" destination="vEO-cI-U7T" id="TZg-36-zRf"/> |
|||
<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="ic_calender" width="25" height="25"/> |
|||
<image name="ic_cancel" width="12" height="12"/> |
|||
</resources> |
|||
<color key="tintColor" red="0.78177064659999995" green="0.55228364470000002" blue="0.018981300289999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> |
|||
</document> |
@ -0,0 +1,128 @@ |
|||
// |
|||
// 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! |
|||
|
|||
// MARK: VC's Life cycle |
|||
override func viewDidLoad() { |
|||
super.viewDidLoad() |
|||
setup() |
|||
} |
|||
|
|||
override func viewWillAppear(_ animated: Bool) { |
|||
super.viewWillAppear(animated) |
|||
|
|||
mainView.bottomToOrigin(duration: 0.1) |
|||
IQKeyboardManager.shared.enable = false |
|||
} |
|||
|
|||
override func viewWillDisappear(_ animated: Bool) { |
|||
super.viewWillDisappear(animated) |
|||
IQKeyboardManager.shared.enable = true |
|||
view.endEditing(true) |
|||
} |
|||
|
|||
// MARK: IBActions |
|||
|
|||
} |
|||
|
|||
// MARK: Other Functions |
|||
extension RecentHistoriesViewController { |
|||
private func setup() { |
|||
// all setup should be done here |
|||
setBinding() |
|||
|
|||
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() |
|||
) |
|||
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) |
|||
|
|||
closeButton.rx.tap |
|||
.bind { |
|||
self.presentingViewController?.view.endEditing(true) |
|||
self.mainView.originToBottom { |
|||
self.dismiss(animated: true) |
|||
} |
|||
}.disposed(by: disposeBag) |
|||
} |
|||
} |
@ -0,0 +1,82 @@ |
|||
// |
|||
// 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> |
|||
} |
|||
|
|||
struct Output { |
|||
let isError: Driver<Error> |
|||
let isProgress: Driver<Bool> |
|||
let histories: Driver<[RecentRecipientModel]> |
|||
let selectedHistory: Driver<RecentRecipientModel?> |
|||
} |
|||
|
|||
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) |
|||
|
|||
return Output( |
|||
isError: errorLinker.asDriverOnErrorJustComplete(), |
|||
isProgress: progressLinker.asDriverOnErrorJustComplete(), |
|||
histories: histories, |
|||
selectedHistory: selectedHistoryLinker.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) |
|||
} |
|||
} |
@ -0,0 +1,14 @@ |
|||
// |
|||
// 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]) |
|||
} |
@ -0,0 +1,50 @@ |
|||
// |
|||
// 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 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) |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
// |
|||
// 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 { |
|||
|
|||
} |
|||
|
|||
protocol RecentHistoriesWireframeOutput: class { |
|||
|
|||
} |
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue