Browse Source

kyc updated

pull/1/head
Dibya Malla 4 years ago
parent
commit
2203953987
  1. BIN
      .DS_Store
  2. 100
      GME Remit.xcodeproj/project.pbxproj
  3. 20
      GME Remit/APIs/Router/APIRouter.swift
  4. 52
      GME Remit/Modules/Profile/Profile.storyboard
  5. 2
      GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/Application Logic/Interactor/UserRegistrationInteractor.swift
  6. 3
      GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/Application Logic/Interactor/UserRegistrationInteractorIO.swift
  7. 2
      GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/Module Interface/UserRegistrationModuleInterface.swift
  8. 12
      GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/User Interface/Presenter/UserRegistrationPresenter.swift
  9. 14
      GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/User Interface/View/UserRegistrationViewController.swift
  10. 1
      GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/User Interface/View/UserRegistrationViewInterface.swift
  11. 10
      GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/User Interface/Wireframe/UserRegistrationWireframe.swift
  12. 3
      GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/User Interface/Wireframe/UserRegistrationWireframeInput.swift
  13. 2
      GME Remit/Modules/RegisterModules/NewUserRegister/Application Logic/Service/NewUserRegisterServiceType.swift
  14. 6
      GME Remit/Modules/RegisterModules/NewUserRegister/User Interface/Wireframe/NewUserRegisterWireframe.swift
  15. 63
      GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/Application Logic/Interactor/ExistingUserKycInteractor.swift
  16. 18
      GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/Application Logic/Interactor/ExistingUserKycInteractorIO.swift
  17. 94
      GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/Application Logic/Service/ExistingUserKycService.swift
  18. 22
      GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/Application Logic/Service/ExistingUserKycServiceType.swift
  19. 281
      GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/User Interface/Presenter/ExistingUserKycPresenter.swift
  20. 910
      GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/User Interface/View/ExistingUserKyc.storyboard
  21. 717
      GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/User Interface/View/ExistingUserKycViewController.swift
  22. 44
      GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/User Interface/Wireframe/ExistingUserKycWireframe.swift
  23. 13
      GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/User Interface/Wireframe/ExistingUserKycWireframeInput.swift
  24. 6
      GME Remit/Modules/RegisterModules/UserAuthentication/KYCVerifyStep1/Application Logic/Service/KYCVerifyStep1Service.swift
  25. 9
      GME Remit/Modules/RegisterModules/UserAuthentication/KYCVerifyStep1/User Interface/View/KYCVerifyStep1ViewController.swift
  26. 16
      GME Remit/Modules/RegisterModules/UserAuthentication/NewRegister/User Interface/Wireframe/NewRegisterWireframe.swift

BIN
.DS_Store

100
GME Remit.xcodeproj/project.pbxproj

@ -79,6 +79,15 @@
40B33AAB24CAF87A00AFE2AB /* ExistingUserRegistrationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B33AA024CAF87A00AFE2AB /* ExistingUserRegistrationViewController.swift */; };
40B33AAC24CAF87A00AFE2AB /* ExistingUserRegistrationViewInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B33AA124CAF87A00AFE2AB /* ExistingUserRegistrationViewInterface.swift */; };
40B33AAD24CAF87A00AFE2AB /* ExistingUserRegistration.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 40B33AA224CAF87A00AFE2AB /* ExistingUserRegistration.storyboard */; };
40B9B0A124EC4ED1002C258C /* ExistingUserKycService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B9B09024EC4ED0002C258C /* ExistingUserKycService.swift */; };
40B9B0A224EC4ED1002C258C /* ExistingUserKycServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B9B09124EC4ED0002C258C /* ExistingUserKycServiceType.swift */; };
40B9B0A324EC4ED1002C258C /* ExistingUserKycInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B9B09324EC4ED0002C258C /* ExistingUserKycInteractor.swift */; };
40B9B0A424EC4ED1002C258C /* ExistingUserKycInteractorIO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B9B09424EC4ED0002C258C /* ExistingUserKycInteractorIO.swift */; };
40B9B0A524EC4ED1002C258C /* ExistingUserKycPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B9B09724EC4ED0002C258C /* ExistingUserKycPresenter.swift */; };
40B9B0A624EC4ED1002C258C /* ExistingUserKycWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B9B09924EC4ED0002C258C /* ExistingUserKycWireframe.swift */; };
40B9B0A724EC4ED1002C258C /* ExistingUserKycWireframeInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B9B09A24EC4ED0002C258C /* ExistingUserKycWireframeInput.swift */; };
40B9B0A824EC4ED1002C258C /* ExistingUserKyc.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 40B9B09D24EC4ED0002C258C /* ExistingUserKyc.storyboard */; };
40B9B0AA24EC4ED1002C258C /* ExistingUserKycViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40B9B09F24EC4ED1002C258C /* ExistingUserKycViewController.swift */; };
40CB8F5824D980D500E1E64E /* NewRegisterRequestModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40CB8F5724D980D400E1E64E /* NewRegisterRequestModel.swift */; };
40D0D35124D2FEB900CEF6B4 /* OldUserRegisterRequestModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40D0D35024D2FEB900CEF6B4 /* OldUserRegisterRequestModel.swift */; };
5565FF1D1FE275E5002934E9 /* SanFranciscoDisplay-Heavy.otf in Resources */ = {isa = PBXBuildFile; fileRef = 5565FF071FE275E0002934E9 /* SanFranciscoDisplay-Heavy.otf */; };
@ -783,6 +792,15 @@
40B33AA024CAF87A00AFE2AB /* ExistingUserRegistrationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExistingUserRegistrationViewController.swift; sourceTree = "<group>"; };
40B33AA124CAF87A00AFE2AB /* ExistingUserRegistrationViewInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExistingUserRegistrationViewInterface.swift; sourceTree = "<group>"; };
40B33AA224CAF87A00AFE2AB /* ExistingUserRegistration.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ExistingUserRegistration.storyboard; sourceTree = "<group>"; };
40B9B09024EC4ED0002C258C /* ExistingUserKycService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExistingUserKycService.swift; sourceTree = "<group>"; };
40B9B09124EC4ED0002C258C /* ExistingUserKycServiceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExistingUserKycServiceType.swift; sourceTree = "<group>"; };
40B9B09324EC4ED0002C258C /* ExistingUserKycInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExistingUserKycInteractor.swift; sourceTree = "<group>"; };
40B9B09424EC4ED0002C258C /* ExistingUserKycInteractorIO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExistingUserKycInteractorIO.swift; sourceTree = "<group>"; };
40B9B09724EC4ED0002C258C /* ExistingUserKycPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExistingUserKycPresenter.swift; sourceTree = "<group>"; };
40B9B09924EC4ED0002C258C /* ExistingUserKycWireframe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExistingUserKycWireframe.swift; sourceTree = "<group>"; };
40B9B09A24EC4ED0002C258C /* ExistingUserKycWireframeInput.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExistingUserKycWireframeInput.swift; sourceTree = "<group>"; };
40B9B09D24EC4ED0002C258C /* ExistingUserKyc.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ExistingUserKyc.storyboard; sourceTree = "<group>"; };
40B9B09F24EC4ED1002C258C /* ExistingUserKycViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExistingUserKycViewController.swift; sourceTree = "<group>"; };
40CB8F5724D980D400E1E64E /* NewRegisterRequestModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewRegisterRequestModel.swift; sourceTree = "<group>"; };
40D0D35024D2FEB900CEF6B4 /* OldUserRegisterRequestModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OldUserRegisterRequestModel.swift; sourceTree = "<group>"; };
5565FF071FE275E0002934E9 /* SanFranciscoDisplay-Heavy.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SanFranciscoDisplay-Heavy.otf"; sourceTree = "<group>"; };
@ -1973,6 +1991,78 @@
path = ViewModels;
sourceTree = "<group>";
};
40B9B08B24EC4ED0002C258C /* ExistingUserKyc */ = {
isa = PBXGroup;
children = (
40B9B08E24EC4ED0002C258C /* Application Logic */,
40B9B09524EC4ED0002C258C /* User Interface */,
);
path = ExistingUserKyc;
sourceTree = "<group>";
};
40B9B08E24EC4ED0002C258C /* Application Logic */ = {
isa = PBXGroup;
children = (
40B9B08F24EC4ED0002C258C /* Service */,
40B9B09224EC4ED0002C258C /* Interactor */,
);
path = "Application Logic";
sourceTree = "<group>";
};
40B9B08F24EC4ED0002C258C /* Service */ = {
isa = PBXGroup;
children = (
40B9B09024EC4ED0002C258C /* ExistingUserKycService.swift */,
40B9B09124EC4ED0002C258C /* ExistingUserKycServiceType.swift */,
);
path = Service;
sourceTree = "<group>";
};
40B9B09224EC4ED0002C258C /* Interactor */ = {
isa = PBXGroup;
children = (
40B9B09324EC4ED0002C258C /* ExistingUserKycInteractor.swift */,
40B9B09424EC4ED0002C258C /* ExistingUserKycInteractorIO.swift */,
);
path = Interactor;
sourceTree = "<group>";
};
40B9B09524EC4ED0002C258C /* User Interface */ = {
isa = PBXGroup;
children = (
40B9B09624EC4ED0002C258C /* Presenter */,
40B9B09824EC4ED0002C258C /* Wireframe */,
40B9B09B24EC4ED0002C258C /* View */,
);
path = "User Interface";
sourceTree = "<group>";
};
40B9B09624EC4ED0002C258C /* Presenter */ = {
isa = PBXGroup;
children = (
40B9B09724EC4ED0002C258C /* ExistingUserKycPresenter.swift */,
);
path = Presenter;
sourceTree = "<group>";
};
40B9B09824EC4ED0002C258C /* Wireframe */ = {
isa = PBXGroup;
children = (
40B9B09924EC4ED0002C258C /* ExistingUserKycWireframe.swift */,
40B9B09A24EC4ED0002C258C /* ExistingUserKycWireframeInput.swift */,
);
path = Wireframe;
sourceTree = "<group>";
};
40B9B09B24EC4ED0002C258C /* View */ = {
isa = PBXGroup;
children = (
40B9B09D24EC4ED0002C258C /* ExistingUserKyc.storyboard */,
40B9B09F24EC4ED1002C258C /* ExistingUserKycViewController.swift */,
);
path = View;
sourceTree = "<group>";
};
5565FF061FE275E0002934E9 /* SanFranciscoFont-master */ = {
isa = PBXGroup;
children = (
@ -3279,6 +3369,7 @@
735F68C92394A76800A2DBC8 /* NewRegister */,
735F68E62394CD6B00A2DBC8 /* NewRegisterStep1 */,
4060B95C24DBBA0200E90F8C /* KYCVerifyStep1 */,
40B9B08B24EC4ED0002C258C /* ExistingUserKyc */,
);
path = UserAuthentication;
sourceTree = "<group>";
@ -6167,6 +6258,7 @@
5565FF251FE275E5002934E9 /* SanFranciscoText-LightItalic.otf in Resources */,
5565FF1F1FE275E5002934E9 /* SanFranciscoText-Regular.otf in Resources */,
73FBBF2223F231A8009D7627 /* NotificationHistory.storyboard in Resources */,
40B9B0A824EC4ED1002C258C /* ExistingUserKyc.storyboard in Resources */,
5565FF291FE275E5002934E9 /* SanFranciscoDisplay-Black.otf in Resources */,
FF6E7D9421BF951D00A003B9 /* AppUpdate.storyboard in Resources */,
D9692A1B221396AF00795EBC /* Setting.storyboard in Resources */,
@ -6572,6 +6664,7 @@
D9D2242B22407EBA00C7313D /* ResendListModel.swift in Sources */,
89739E4524459A630016251B /* SendMoneyExchangeRateService.swift in Sources */,
D92B80262140C3CB00A25B26 /* MainService.swift in Sources */,
40B9B0A424EC4ED1002C258C /* ExistingUserKycInteractorIO.swift in Sources */,
89739E2C24459A630016251B /* SendMoneyParentService.swift in Sources */,
D9B414422161AE2800A53D9D /* DatePickerViewController.swift in Sources */,
89EA0D77243EC1C5003ACCC8 /* PersonalInformationServiceType.swift in Sources */,
@ -6791,6 +6884,7 @@
73210DA322FBE73100715D6C /* RecipientsServiceType.swift in Sources */,
73210DA822FBE73100715D6C /* RecipientsWireframeInputOutput.swift in Sources */,
89739E6124459A630016251B /* SendMoneyVerificationWireframeInput.swift in Sources */,
40B9B0A524EC4ED1002C258C /* ExistingUserKycPresenter.swift in Sources */,
89739E5B24459A630016251B /* SendMoneyVerificationServiceType.swift in Sources */,
73185350230EACA400BA9AE3 /* SendMoneyCountryViewModel.swift in Sources */,
4060B98124DBD22C00E90F8C /* PersonalInfoModel.swift in Sources */,
@ -6808,6 +6902,7 @@
BEC9B001224FC49C00A2DA06 /* BiometricAuthenticationPresenter.swift in Sources */,
73157BA722DC3F14009B836F /* Date+Ext.swift in Sources */,
89EA0D75243EC1C5003ACCC8 /* PersonalInformationContainer.swift in Sources */,
40B9B0AA24EC4ED1002C258C /* ExistingUserKycViewController.swift in Sources */,
7E692A7824AF190B00F10D62 /* OTPSubmitViewInterface.swift in Sources */,
7303E5732344A1F000472407 /* StoreReviewHelper.swift in Sources */,
89739E2A24459A630016251B /* SendMoneyParentModuleInterface.swift in Sources */,
@ -6841,6 +6936,7 @@
89739E2D24459A630016251B /* SendMoneyParentInteractor.swift in Sources */,
7EDBFBFF24B3031B00AD5D4D /* WithdrawFromWalletServiceType.swift in Sources */,
D946719A21426DFB003924DB /* LoginPresenter.swift in Sources */,
40B9B0A224EC4ED1002C258C /* ExistingUserKycServiceType.swift in Sources */,
D92B802C2140C3CB00A25B26 /* MainWireframe.swift in Sources */,
89739E6324459A630016251B /* SendMoneyVerificationViewInterface.swift in Sources */,
73AEFF752334A13100A967FB /* TransactionHistoryGroupPresenter.swift in Sources */,
@ -6863,6 +6959,7 @@
D946719521426DFB003924DB /* LoginModuleInterface.swift in Sources */,
7389600E22C2F208003FEA90 /* TablePresenterInteractor.swift in Sources */,
7EDBFC2524B3098E00AD5D4D /* WithdrawFromWalletDetailService.swift in Sources */,
40B9B0A324EC4ED1002C258C /* ExistingUserKycInteractor.swift in Sources */,
4060B97324DBBA0300E90F8C /* KYCVerifyStep1ServiceType.swift in Sources */,
73157B9E22DC1EEC009B836F /* PopupNotificationInteractor.swift in Sources */,
D96BD1262164875800DFE7D8 /* WalletStatementTableViewCell.swift in Sources */,
@ -6875,6 +6972,7 @@
738B6B5523F4E6F0006FA928 /* DetailNoticeModel.swift in Sources */,
042E6EFD203EAF95004667A1 /* SideMenuViewController.swift in Sources */,
73AEFF792334A13100A967FB /* TransactionHistoryGroupViewModel.swift in Sources */,
40B9B0A124EC4ED1002C258C /* ExistingUserKycService.swift in Sources */,
73FBBF2023F231A8009D7627 /* NotificationHistoryWireframe.swift in Sources */,
D9535CCC2150C14700EDFCD2 /* KYCResponseModel.swift in Sources */,
D96A4FD621460B4A00CFD507 /* SplashScreenServiceType.swift in Sources */,
@ -6925,6 +7023,7 @@
D92B80292140C3CB00A25B26 /* MainInteractorIO.swift in Sources */,
73976D202331B4F4003CF5E1 /* UIImageView+Ext.swift in Sources */,
0496B84F1FE7DFCD0044810E /* String+Ext.swift in Sources */,
40B9B0A624EC4ED1002C258C /* ExistingUserKycWireframe.swift in Sources */,
735F68E32394A76800A2DBC8 /* NewRegisterViewController.swift in Sources */,
D9B7ADF52130048E009B0564 /* ExchangeRatesPresenter.swift in Sources */,
73A6E20422CEE51600E9BC68 /* BadgeLabel.swift in Sources */,
@ -6957,6 +7056,7 @@
D9B7ADFD2130073A009B0564 /* WireframeInput.swift in Sources */,
73195AB722FD14D500151434 /* SetupRecipientPresenter.swift in Sources */,
73149F6D22E5AF8000D66B26 /* LauncherScreenViewController.swift in Sources */,
40B9B0A724EC4ED1002C258C /* ExistingUserKycWireframeInput.swift in Sources */,
892F9E90243DB42D00D9D88C /* ShowAPITableViewCell.swift in Sources */,
73149F6922E5AF8000D66B26 /* LauncherScreenWireframeInput.swift in Sources */,
D96BD1232164870C00DFE7D8 /* DateFormatter+Ext.swift in Sources */,

20
GME Remit/APIs/Router/APIRouter.swift

@ -43,6 +43,7 @@ enum APIRouter {
// MARK: - Existing User Registration
case oldUserAccessRequest(idNumber: String, mobileNumber: String, dob: String)
case oldUserRegister(registerModel: OldUserRegisterRequestModel, firebaseToken: String)
case submitExistingCustomerKYC(model: KYCSaveInformation)
// MARK: - New User Registration
case verifyIdNumber(id: String, type: String)
@ -461,6 +462,8 @@ extension APIRouter {
return "\(baseUrlWithoutVersion)/v4/mobile/RegisterKyc"
case .submitKYC:
return "\(baseUrlWithoutVersion)v1/mobile/RegisterKyc"
case .submitExistingCustomerKYC:
return "\(baseUrlWithoutVersion)v1/mobile/submitExistingCustomerKYC"
case .requestPennyTestAtRegister(let resend):
let userID = GMEDB.shared.user.string(.userId) ?? ""
return "\(baseUrl)/mobile/pennytest/start/\(userID)?reSendCode=\(resend)"
@ -555,6 +558,8 @@ extension APIRouter {
return .post
case .submitKYC:
return .post
case .submitExistingCustomerKYC:
return .post
case .requestPennyTestAtRegister:
return .post
case .fetchKFTCParameterForRegister:
@ -834,6 +839,21 @@ extension APIRouter {
"userId": GMEDB.shared.user.string(.userId) ?? ""
]
case .submitExistingCustomerKYC(let model):
return [
"type": "0",
"occupation": model.personalInformation?.occupation ?? "",
"sourceOfFund": model.personalInformation?.sourceOfFund ?? "",
"monthlyIncome": model.personalInformation?.monthlyIncome ?? "",
"businessType": model.personalInformation?.businessType ?? "",
"mobile": model.personalInformation?.mobile ?? "",
"email": model.personalInformation?.email ?? "",
"additionalAddress": model.personalInformation?.address ?? "",
"idType": model.personalInformation?.idType ?? "",
"additionalIdType": model.personalInformation?.additionalIdType ?? "",
"userId": GMEDB.shared.user.string(.userId) ?? ""
]
case .pennyTestSubmitAtRegister(let accountNumber, let certNumber):
let senderID = GMEDB.shared.user.string(.senderId) ?? ""
return [

52
GME Remit/Modules/Profile/Profile.storyboard

@ -389,7 +389,7 @@
<nil key="highlightedColor"/>
</label>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hfP-aZ-zbf" userLabel="Camera">
<rect key="frame" x="204.66666666666666" y="87" width="16" height="16"/>
<rect key="frame" x="204.66666666666666" y="87" width="32" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="16" id="Q5Z-vM-fgo"/>
</constraints>
@ -419,7 +419,7 @@
<rect key="frame" x="10" y="248" width="355" height="167"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Your Available Balance" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mmh-uV-sP4">
<rect key="frame" x="30" y="18" width="143" height="13"/>
<rect key="frame" x="30" y="18" width="142.66666666666666" height="13"/>
<fontDescription key="fontDescription" name="SanFranciscoText-Regular" family="San Francisco Text" pointSize="14"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
@ -428,7 +428,7 @@
<rect key="frame" x="20" y="65" width="315" height="21"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="asldkjfalsdkfjaskdlfjasdklfjkasdf" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="nlo-iP-QwN">
<rect key="frame" x="10" y="2" width="191.66666666666666" height="17"/>
<rect key="frame" x="10" y="2" width="191.66666666666666" height="16.333333333333332"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="13" id="Vul-Ou-98m"/>
</constraints>
@ -437,7 +437,7 @@
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="91028120938112" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="hkj-cL-iCj">
<rect key="frame" x="205" y="2" width="100" height="17"/>
<rect key="frame" x="205" y="2" width="100" height="16.333333333333332"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="GGp-iK-ZUJ"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="13" id="dAY-tV-MW7"/>
@ -458,7 +458,7 @@
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="..." lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="MAZ-i9-fR8">
<rect key="frame" x="30" y="33" width="21" height="28"/>
<rect key="frame" x="30" y="33" width="20.333333333333329" height="28"/>
<constraints>
<constraint firstAttribute="height" constant="28" id="bd9-CU-FEm"/>
</constraints>
@ -467,7 +467,7 @@
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="JPY" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EXY-5m-shp">
<rect key="frame" x="55" y="43" width="23" height="14"/>
<rect key="frame" x="54.333333333333321" y="43" width="25.666666666666664" height="14"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="cBG-w2-z4r"/>
</constraints>
@ -485,16 +485,16 @@
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="sKv-XW-oIC">
<rect key="frame" x="29.999999999999986" y="121" width="198.66666666666663" height="21"/>
<rect key="frame" x="29.999999999999986" y="121" width="205.66666666666663" height="21"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ReferralCode:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lid-5n-35E">
<rect key="frame" x="0.0" y="0.0" width="88" height="21"/>
<rect key="frame" x="0.0" y="0.0" width="86.666666666666671" height="21"/>
<fontDescription key="fontDescription" name="SanFranciscoText-Regular" family="San Francisco Text" pointSize="14"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="123123123123131" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fPb-ME-3gX">
<rect key="frame" x="90" y="0.0" width="108.66666666666669" height="21"/>
<rect key="frame" x="88.666666666666657" y="0.0" width="117" height="21"/>
<fontDescription key="fontDescription" name="SanFranciscoText-Regular" family="San Francisco Text" pointSize="14"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
@ -538,7 +538,7 @@
<rect key="frame" x="10" y="425" width="355" height="70"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Remaining Yearly Limit" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4mc-iJ-afH">
<rect key="frame" x="30" y="10" width="146" height="17"/>
<rect key="frame" x="30" y="10" width="142" height="17"/>
<fontDescription key="fontDescription" name="SanFranciscoText-Regular" family="San Francisco Text" pointSize="14"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
@ -587,7 +587,7 @@
<rect key="frame" x="149" y="191" width="77" height="0.0"/>
<subviews>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bv9-cG-fQQ">
<rect key="frame" x="0.0" y="0.0" width="93" height="17"/>
<rect key="frame" x="0.0" y="0.0" width="99" height="17"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="MrC-na-8TP"/>
</constraints>
@ -695,7 +695,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="724"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LU1-7H-4oT">
<rect key="frame" x="10" y="87" width="355" height="264"/>
<rect key="frame" x="10" y="86" width="355" height="264"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="9" translatesAutoresizingMaskIntoConstraints="NO" id="zMD-Ic-UA3">
<rect key="frame" x="0.0" y="0.0" width="355" height="264"/>
@ -704,7 +704,7 @@
<rect key="frame" x="0.0" y="0.0" width="355" height="82"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Current Password" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7Gs-uo-Wte">
<rect key="frame" x="28.000000000000007" y="15" width="106.66666666666669" height="17"/>
<rect key="frame" x="28.000000000000007" y="15" width="112.66666666666669" height="17"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="Shc-Al-nF8"/>
</constraints>
@ -713,7 +713,7 @@
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Enter your Current Password" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="zfD-X4-YTt">
<rect key="frame" x="28.000000000000014" y="37" width="219.33333333333337" height="31"/>
<rect key="frame" x="27.999999999999986" y="37" width="232.66666666666663" height="31"/>
<constraints>
<constraint firstAttribute="height" constant="31" id="1ut-5w-QgJ"/>
</constraints>
@ -739,7 +739,7 @@
<rect key="frame" x="0.0" y="91" width="355" height="82"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="New Password" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iZO-Jd-Wum">
<rect key="frame" x="28" y="15" width="88" height="17"/>
<rect key="frame" x="27.999999999999993" y="15" width="94.333333333333314" height="17"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="PQ1-TF-F6e"/>
</constraints>
@ -748,7 +748,7 @@
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Enter your New Password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="GwX-M7-rY8">
<rect key="frame" x="28" y="37" width="195" height="31"/>
<rect key="frame" x="27.999999999999986" y="37" width="208.66666666666663" height="31"/>
<constraints>
<constraint firstAttribute="height" constant="31" id="RjL-Vy-18n"/>
</constraints>
@ -774,7 +774,7 @@
<rect key="frame" x="0.0" y="182" width="355" height="82"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Confirm Password" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ivp-u7-qDI">
<rect key="frame" x="28" y="15" width="110" height="17"/>
<rect key="frame" x="28.000000000000007" y="15" width="115.66666666666669" height="17"/>
<constraints>
<constraint firstAttribute="height" constant="17" id="h2C-uP-gzp"/>
</constraints>
@ -783,7 +783,7 @@
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Confirm your Password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="V5J-Sb-fhg">
<rect key="frame" x="28" y="37" width="179" height="31"/>
<rect key="frame" x="28" y="37" width="189" height="31"/>
<constraints>
<constraint firstAttribute="height" constant="31" id="zaC-Tw-UP6"/>
</constraints>
@ -818,7 +818,7 @@
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cdu-5Q-Z5A">
<rect key="frame" x="10" y="21" width="355" height="43"/>
<rect key="frame" x="10" y="21" width="355" height="42"/>
<string key="text">Password should be At least one symbol,
At least one capital letter, At least one number
Be at least 9 characters</string>
@ -827,7 +827,7 @@ At least one capital letter, At least one number
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MGk-Ef-gDh">
<rect key="frame" x="38" y="391" width="299" height="50"/>
<rect key="frame" x="38" y="390" width="299" height="50"/>
<color key="backgroundColor" red="1" green="0.1529411765" blue="0.1529411765" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="Hbc-yX-TKi"/>
@ -904,10 +904,10 @@ At least one capital letter, At least one number
<rect key="frame" x="0.0" y="44" width="375" height="734"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZGq-YR-tsm">
<rect key="frame" x="0.0" y="0.0" width="375" height="670"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="669"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="46P-ck-y0O">
<rect key="frame" x="38" y="87" width="299" height="200"/>
<rect key="frame" x="38" y="86" width="299" height="200"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="9" translatesAutoresizingMaskIntoConstraints="NO" id="7xD-Q7-hHh">
<rect key="frame" x="0.0" y="0.0" width="299" height="200"/>
@ -943,7 +943,7 @@ At least one capital letter, At least one number
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qbz-3b-6Ps">
<rect key="frame" x="10" y="21" width="355" height="43"/>
<rect key="frame" x="10" y="21" width="355" height="42"/>
<string key="text">Password should be At least one symbol,
At least one capital letter, At least one number
Be at least 9 characters</string>
@ -952,7 +952,7 @@ At least one capital letter, At least one number
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1aA-0c-NOM">
<rect key="frame" x="38" y="327" width="299" height="50"/>
<rect key="frame" x="38" y="326" width="299" height="50"/>
<color key="backgroundColor" red="1" green="0.1529411765" blue="0.1529411765" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="pge-KY-IKd"/>
@ -1039,7 +1039,7 @@ At least one capital letter, At least one number
</userDefinedRuntimeAttributes>
</textField>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Let us know your reason for withdraw." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2gL-Zv-Fug">
<rect key="frame" x="34.333333333333343" y="27" width="306.66666666666663" height="21"/>
<rect key="frame" x="33.333333333333343" y="27" width="308.66666666666663" height="21"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="rfm-0C-Wkc"/>
</constraints>
@ -1063,7 +1063,7 @@ At least one capital letter, At least one number
</userDefinedRuntimeAttributes>
</textView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Note: 1000 JPY will be charged for per request." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BXg-eg-tI4">
<rect key="frame" x="39.333333333333343" y="286" width="296.66666666666663" height="17"/>
<rect key="frame" x="49.333333333333343" y="286" width="276.66666666666663" height="17"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="16" id="3oQ-JO-qXk"/>
</constraints>

2
GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/Application Logic/Interactor/UserRegistrationInteractor.swift

@ -41,7 +41,7 @@ extension UserRegistrationInteractor: UserRegistrationInteractorInput {
password: model.password ?? "",
success: { user in
GMEDB.shared.user.set(user?.accessCode, .accessCode)
self.output?.loggedIn()
self.output?.loggedIn(message: message ?? "")
},
failure: {
self.output?.show(error: $0)

3
GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/Application Logic/Interactor/UserRegistrationInteractorIO.swift

@ -12,5 +12,6 @@ protocol UserRegistrationInteractorInput: class {
protocol UserRegistrationInteractorOutput: class {
func show(error: Error)
func loggedIn()
func success(message: String)
func loggedIn(message: String)
}

2
GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/Module Interface/UserRegistrationModuleInterface.swift

@ -8,4 +8,6 @@
protocol UserRegistrationModuleInterface: class {
func oldUserRegister(model: OldUserRegisterRequestModel)
func showKyc()
}

12
GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/User Interface/Presenter/UserRegistrationPresenter.swift

@ -27,18 +27,26 @@ extension UserRegistrationPresenter: UserRegistrationModuleInterface {
self.interactor?.oldUserRegister(model: model)
}
func showKyc() {
self.wireframe?.showKyc()
}
}
// MARK: UserRegistration interactor output interface
extension UserRegistrationPresenter: UserRegistrationInteractorOutput {
func loggedIn(message:String) {
self.view?.hideLoading()
self.view?.loggedIn(message: message)
}
func show(error: Error) {
self.view?.hideLoading()
self.view?.show(error: error.localizedDescription)
}
func loggedIn() {
func success(message: String) {
self.view?.hideLoading()
self.wireframe?.dashBoard()
}
}

14
GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/User Interface/View/UserRegistrationViewController.swift

@ -188,4 +188,18 @@ extension UserRegistrationViewController: UserRegistrationViewInterface {
self.alert(type: .error, message: error)
}
func loggedIn(message: String) {
self.alertWithOk(
type: .success,
message: message,
title: "Success",
okTitle: "Ok"
) {
// guard let id = self.userIDTxtField.text else {
// return
// }
// GMEDB.shared.user.set(id, .userId)
self.presenter?.showKyc()
}
}
}

1
GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/User Interface/View/UserRegistrationViewInterface.swift

@ -10,4 +10,5 @@ protocol UserRegistrationViewInterface: class {
func showLoading()
func hideLoading()
func show(error: String)
func loggedIn(message: String)
}

10
GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/User Interface/Wireframe/UserRegistrationWireframe.swift

@ -7,7 +7,6 @@
//
import UIKit
import LGSideMenuController
class UserRegistrationWireframe {
weak var view: UIViewController!
@ -32,7 +31,7 @@ extension UserRegistrationWireframe: UserRegistrationWireframeInput {
self.view = viewController
return viewController
}
/*
func dashBoard() {
guard let sidemenuVc = UIStoryboard(
name: "SideMenu",
@ -62,5 +61,12 @@ extension UserRegistrationWireframe: UserRegistrationWireframeInput {
window?.backgroundColor = sidemenuVc.view.backgroundColor
self.window?.rootViewController = sideMenuController
}
*/
func showKyc() {
// ManageAgreementWireframe().pushWithNavigation(on: view)
if let navigation = self.view.navigationController {
NewRegisterWireframe().selectedView(in: navigation, viewName: "ExistingUser")
}
}
}

3
GME Remit/Modules/RegisterModules/ExistingUserRegistration/UserRegistration/User Interface/Wireframe/UserRegistrationWireframeInput.swift

@ -9,5 +9,6 @@
import Foundation
protocol UserRegistrationWireframeInput: WireframeInput {
func dashBoard()
// func dashBoard()
func showKyc()
}

2
GME Remit/Modules/RegisterModules/NewUserRegister/Application Logic/Service/NewUserRegisterServiceType.swift

@ -10,7 +10,7 @@ import Foundation
protocol NewUserRegisterServiceType: class, UserRegisterService { }
protocol UserRegisterService {
protocol UserRegisterService: ApiServiceType {
func userRegister(
model: NewUserRegisterModel,
token: String,

6
GME Remit/Modules/RegisterModules/NewUserRegister/User Interface/Wireframe/NewUserRegisterWireframe.swift

@ -33,6 +33,10 @@ extension NewUserRegisterWireframe: NewUserRegisterWireframeInput {
}
func showKyc() {
ManageAgreementWireframe().pushWithNavigation(on: view)
// ManageAgreementWireframe().pushWithNavigation(on: view)
if let navigation = self.view.navigationController {
NewRegisterWireframe().pushMainView(in: navigation)
}
}
}

63
GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/Application Logic/Interactor/ExistingUserKycInteractor.swift

@ -0,0 +1,63 @@
//
// ExistingUserKycInteractor.swift
// GME Remit
//
// Created by Shiran on 8/18/20.
//Copyright © 2020 Gobal Money Express Co. Ltd. All rights reserved.
//
import Foundation
class ExistingUserKycInteractor {
// MARK: Properties
weak var output: ExistingUserKycInteractorOutput?
private let service: ExistingUserKycServiceType
private var saveModel: KYCSaveInformation?
private var storedModel: KYCInfoModel?
// MARK: Initialization
init(service: ExistingUserKycServiceType) {
self.service = service
}
// MARK: Converting entities
}
// MARK: ExistingUserKyc interactor input interface
extension ExistingUserKycInteractor: ExistingUserKycInteractorInput {
func fetchInformation() {
service.fetchKycInfo(
success: {[weak self] in
self?.storedModel = $0
self?.output?.setModel(with: $0)
},
failure: {[weak self] in
self?.output?.setError(with: $0)
}
)
}
func saveInformation(with model: KYCSaveInformation) {
saveModel = model
if let storedData = self.storedModel {
saveModel?.personalInformation = model.personalInformation ?? storedData.personalInformation
saveModel?.pictures = model.pictures ?? storedData.pictures
service.saveKycInfo(
with: saveModel!,
success: {[weak self] in
self?.output?.setSaveResult(with: self?.saveModel, message: $0)
},
failure: {[weak self] in
self?.output?.setError(with: $0)
}
)
}
}
}

18
GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/Application Logic/Interactor/ExistingUserKycInteractorIO.swift

@ -0,0 +1,18 @@
//
// ExistingUserKycInteractorIO.swift
// GME Remit
//
// Created by Shiran on 8/18/20.
//Copyright © 2020 Gobal Money Express Co. Ltd. All rights reserved.
//
protocol ExistingUserKycInteractorInput: class {
func fetchInformation()
func saveInformation(with model: KYCSaveInformation)
}
protocol ExistingUserKycInteractorOutput: class {
func setModel(with model: KYCInfoModel)
func setSaveResult(with storedModel: KYCSaveInformation?, message: String)
func setError(with error: Error)
}

94
GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/Application Logic/Service/ExistingUserKycService.swift

@ -0,0 +1,94 @@
//
// ExistingUserKycService.swift
// GME Remit
//
// Created by Shiran on 8/18/20.
//Copyright © 2020 Gobal Money Express Co. Ltd. All rights reserved.
//
import Foundation
import UIKit
class ExistingUserKycService: ExistingUserKycServiceType {
func fetchKycInfo(
success: @escaping (KYCInfoModel) -> Void,
failure: @escaping (Error) -> Void
) {
APIRouter.loadKYCInformation.json(
needsAuthorization: false,
success: success,
failure: failure
)
}
func saveKycInfo(
with model: KYCSaveInformation,
success: @escaping (String) -> Void,
failure: @escaping (Error) -> Void
) {
APIRouter.submitKYC(model: model)
.requestMultipart(
images: getImageParams(model: model),
needsAuthorization: true,
success: { (response: KYCResponseContainer) in
if (response.errorCode ?? "") == "1" {
let error = NSError(
domain: "Network",
code: 0,
userInfo: [NSLocalizedDescriptionKey : response.message ?? ""]
)
failure(error)
} else {
guard let message = response.message else {
return
}
if let senderID = response.senderID {
GMEDB.shared.user.set(senderID, .senderId)
}
success(message)
}
},
failure: failure)
}
private func getCompressedImage(base64: String) -> Data? {
guard let imageData = Data(base64Encoded: base64) else { return nil }
return UIImage(data: imageData)?.jpegData(compressionQuality: 0.6)
}
private func getImageParams(model: KYCSaveInformation) -> [String: Data] {
var images: [String: Data] = [:]
let model = model.pictures
// frontIDPicture
if let image = model?.frontIDPicture {
if let data = getCompressedImage(base64: image) {
images["idFront"] = data
}
}
// backIDPicture
if let image = model?.backIDPicture {
if let data = getCompressedImage(base64: image) {
images["idBack"] = data
}
}
// sideIDPicture
if let image = model?.sideIDPicture {
if let data = getCompressedImage(base64: image) {
images["idSide"] = data
}
}
// additionalIDPicture
if let image = model?.additionalIDPicture {
if let data = getCompressedImage(base64: image) {
images["additionalId"] = data
}
}
return images
}
}

22
GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/Application Logic/Service/ExistingUserKycServiceType.swift

@ -0,0 +1,22 @@
//
// ExistingUserKycServiceType.swift
// GME Remit
//
// Created by Shiran on 8/18/20.
//Copyright © 2020 Gobal Money Express Co. Ltd. All rights reserved.
//
import Foundation
protocol ExistingUserKycServiceType: class {
func fetchKycInfo(
success: @escaping (KYCInfoModel) -> Void,
failure: @escaping (Error) -> Void
)
func saveKycInfo(
with model: KYCSaveInformation,
success: @escaping (String) -> Void,
failure: @escaping (Error) -> Void
)
}

281
GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/User Interface/Presenter/ExistingUserKycPresenter.swift

@ -0,0 +1,281 @@
//
// ExistingUserKycPresenter.swift
// GME Remit
//
// Created by Shiran on 8/18/20.
//Copyright © 2020 Gobal Money Express Co. Ltd. All rights reserved.
//
import RxSwift
import RxCocoa
import CoreLocation
class ExistingUserKycPresenter {
// MARK: Properties
enum Step: Int {
case innerStep1
case innerStep2
}
var interactor: ExistingUserKycInteractorInput?
var wireframe: ExistingUserKycWireframeInput?
struct Input {
let viewWillAppear: Driver<Bool>
let sendLocation: Driver<CLLocation>
let employerName: Driver<String>
let sourceOfFund: Driver<KeyValue?>
let monthlyIncome: Driver<KeyValue?>
let businessType: Driver<KeyValue?>
let idType: Driver<KeyValue?>
let additionalIdType: Driver<KeyValue?>
let mobile: Driver<String>
let email: Driver<String>
let address: Driver<String>
let isValidPersonalInfo: Driver<Bool>
let personalInfoSave: Driver<Void>
let editingPersonalInfo: Driver<Void>
let frontIDImage: Driver<String?>
let backIDImage: Driver<String?>
let sideIDImage: Driver<String?>
let additionalIDImage: Driver<String?>
let facePicture: Driver<String?>
let isValidPictures: Driver<Bool>
let editingPictureInfo: Driver<Void>
let submit: Driver<Void>
}
struct Output {
let isError: Driver<Error>
let isProgress: Driver<Bool>
let gpsAddress: Driver<String>
let model: Driver<KYCInfoModel>
let idTypes: Driver<[KeyValue]?>
let additionaIDType: Driver<[KeyValue]?>
let busniessType: Driver<[KeyValue]?>
let sourceOfFund: Driver<[KeyValue]?>
let monthlyIncome: Driver<[KeyValue]?>
let isSetPersonalInfoModel: Driver<Bool>
let isSetPictureInfoModel: Driver<Bool>
let storePersonalSuccess: Driver<Bool>
let storedSuccess: Driver<String>
}
private let disposeBag = DisposeBag()
private let progressLinker = PublishSubject<Bool>()
private let errorLinker = PublishSubject<Error>()
private let gpsAddress = PublishSubject<String>()
private let model = PublishSubject<KYCInfoModel>()
private var storedPersonalInfo = PublishSubject<PersonalInfoModel?>()
private var storedPictureInformation = PublishSubject<PictureInfoModel?>()
private var storedPersonalSuccess = PublishSubject<String?>()
private let storedSuccess = PublishSubject<String>()
func transform(input: Input) -> Output {
let newPicturesInfo = Driver.combineLatest(
input.isValidPictures,
input.frontIDImage,
input.backIDImage,
input.sideIDImage,
input.additionalIDImage,
input.facePicture
).map { (isValid, frontIdImage, backIdImage, sideIdImage, additionalIdImage, facePicture) -> PictureInfoModel? in
return isValid ? PictureInfoModel(idFront: frontIdImage, idBack: backIdImage, idSide: sideIdImage, additionalId: additionalIdImage, facePicture: facePicture) : nil
}
let newPersonalInfo = Driver.combineLatest(
input.isValidPersonalInfo,
input.idType,
input.additionalIdType,
Driver.combineLatest(
input.employerName,
input.sourceOfFund,
input.monthlyIncome,
input.mobile,
input.businessType,
input.email,
input.address,
model.map{$0.personalInformation?.nativeCountry}.asDriverOnErrorJustComplete()
).map({ (employerName, sourceOfFund, monthlyIncome, mobile, businessType, email, address, nativeCountry) -> PersonalInfoModel in
return PersonalInfoModel(
email: email,
address: address,
occupation: employerName,
sourceOfFund: sourceOfFund?.id,
monthlyIncome: monthlyIncome?.id,
mobile: mobile,
idType: nil,
additionalIdType: nil,
businessType: businessType?.id,
nativeCountry: nativeCountry)
})
).map { (isValid, idType, additionalIdType, info) -> PersonalInfoModel? in
if isValid{
var personalInfo = info
personalInfo.idType = idType?.id
personalInfo.additionalIdType = additionalIdType?.id
return personalInfo
}
return nil
}
let isSetPersonalInformation = Driver
.combineLatest(input.isValidPersonalInfo, storedPersonalInfo.asDriverOnErrorJustComplete())
.map { $0 && $1 != nil }
let isSetPictureInformation = Driver
.combineLatest(input.isValidPictures, storedPictureInformation.asDriverOnErrorJustComplete())
.map {$0 && $1 != nil}
let storePersonalSuccess = Driver
.combineLatest(input.isValidPersonalInfo, storedPersonalSuccess.asDriverOnErrorJustComplete())
.map {$0 && $1 != nil}
input.viewWillAppear.drive(onNext: { [weak self] (value) in
self?.progressLinker.onNext(value)
self?.interactor?.fetchInformation()
}).disposed(by: disposeBag)
input.sendLocation.drive(onNext: { [weak self] in
self?.progressLinker.onNext(true)
let geocoder = CLGeocoder()
let locale = Locale(identifier: "en-US")
geocoder.reverseGeocodeLocation($0, preferredLocale: locale) {(placemarks, error) in
if let error = error {
self?.progressLinker.onNext(false)
self?.errorLinker.onNext(error)
}
if let address: [CLPlacemark] = placemarks {
let name = address.last?.name ?? ""
let locality = address.last?.locality ?? ""
self?.progressLinker.onNext(false)
let mergedAddress = "\(name) \(locality)"//.extract(regex: "[A-Z0-9a-z\\s]")
self?.gpsAddress.onNext(mergedAddress)
}
}
}).disposed(by: disposeBag)
input.editingPersonalInfo
.withLatestFrom(newPersonalInfo) { $1 }
.withLatestFrom(storedPersonalInfo.asDriverOnErrorJustComplete()) {($0, $1)}
.drive(onNext: {[weak self] in
guard let new = $0, let stored = $1 else { return }
if new != stored {
self?.storedPersonalInfo.onNext(nil)
}
})
.disposed(by: disposeBag)
input.editingPictureInfo
.withLatestFrom(newPicturesInfo) { $1 }
.withLatestFrom(storedPictureInformation.asDriverOnErrorJustComplete()) {($0, $1)}
.drive(onNext: {[weak self] in
guard let new = $0, let stored = $1 else { return }
if new != stored {
self?.storedPictureInformation.onNext(nil)
}
})
.disposed(by: disposeBag)
input.personalInfoSave
.withLatestFrom(newPersonalInfo) { $1 }
.drive(onNext: {[weak self] in
let saveModel = KYCSaveInformation(
type: Step.innerStep1.rawValue,
personalInformation: $0,
pictures: nil
)
self?.progressLinker.onNext(true)
self?.interactor?.saveInformation(with: saveModel)
}).disposed(by: disposeBag)
input.submit
.withLatestFrom(newPersonalInfo) { $1 }
.withLatestFrom(newPicturesInfo) { ($0, $1) }
.drive(onNext: {[weak self] in
let saveModel = KYCSaveInformation(
type: Step.innerStep2.rawValue,
personalInformation: $0,
pictures: $1
)
self?.progressLinker.onNext(true)
self?.interactor?.saveInformation(with: saveModel)
}).disposed(by: disposeBag)
return Output(
isError: errorLinker.asDriverOnErrorJustComplete(),
isProgress: progressLinker.asDriverOnErrorJustComplete(),
gpsAddress: gpsAddress.asDriverOnErrorJustComplete(),
model: model.asDriverOnErrorJustComplete(),
idTypes: model.map {$0.idType}.asDriverOnErrorJustComplete(),
additionaIDType: model.map {$0.additionalIdType}.asDriverOnErrorJustComplete(),
busniessType: model.map {$0.businessType}.asDriverOnErrorJustComplete(),
sourceOfFund: model.map {$0.sourceOfFund}.asDriverOnErrorJustComplete(),
monthlyIncome: model.map {$0.monthlyIncome}.asDriverOnErrorJustComplete(),
isSetPersonalInfoModel: isSetPersonalInformation,
isSetPictureInfoModel: isSetPictureInformation,
storePersonalSuccess: storePersonalSuccess,
storedSuccess: storedSuccess.asDriverOnErrorJustComplete()
)
}
}
// MARK: ExistingUserKyc interactor output interface
extension ExistingUserKycPresenter: ExistingUserKycInteractorOutput {
func setModel(with model: KYCInfoModel) {
progressLinker.onNext(false)
self.model.onNext(model)
guard let personalInformation = model.personalInformation, !personalInformation.isHasEmptyValue() else {
storedPersonalInfo.onNext(nil)
return
}
storedPersonalInfo.onNext(model.personalInformation)
guard let pictures = model.pictures, !pictures.isHasEmptyValue() else {
storedPictureInformation.onNext(nil)
return
}
storedPictureInformation.onNext(pictures)
}
func setSaveResult(with storedModel: KYCSaveInformation?, message: String) {
progressLinker.onNext(false)
guard let storedModel = storedModel, let type = Step(rawValue: storedModel.type) else { return }
switch type {
case .innerStep1:
storedPersonalInfo.onNext(storedModel.personalInformation)
storedPersonalSuccess.onNext(message)
case .innerStep2:
storedPictureInformation.onNext(storedModel.pictures)
storedSuccess.onNext(message)
}
}
func setError(with error: Error) {
progressLinker.onNext(false)
errorLinker.onNext(error)
}
}

910
GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/User Interface/View/ExistingUserKyc.storyboard

@ -0,0 +1,910 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="HSb-ou-7T5">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<customFonts key="customFonts">
<array key="SanFranciscoDisplay-Medium.otf">
<string>SanFranciscoDisplay-Medium</string>
</array>
<array key="SanFranciscoDisplay-Regular.otf">
<string>SanFranciscoDisplay-Regular</string>
</array>
</customFonts>
<scenes>
<!--ExistingUserKyc-->
<scene sceneID="R60-Pu-Hpy">
<objects>
<viewController storyboardIdentifier="ExistingUserKycViewController" title="ExistingUserKyc" id="HSb-ou-7T5" customClass="ExistingUserKycViewController" customModule="Fast_Remit" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y1H-iV-BwG"/>
<viewControllerLayoutGuide type="bottom" id="PYB-Kq-ghm"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="9Uc-9s-KgO">
<rect key="frame" x="0.0" y="0.0" width="375" height="1700"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HAO-EE-YnY">
<rect key="frame" x="0.0" y="0.0" width="375" height="1700"/>
<subviews>
<view contentMode="scaleToFill" placeholderIntrinsicWidth="375" placeholderIntrinsicHeight="594.5" translatesAutoresizingMaskIntoConstraints="NO" id="TF6-Vy-Vuj">
<rect key="frame" x="0.0" y="0.0" width="375" height="1592"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YV6-LS-yFu">
<rect key="frame" x="10" y="10" width="355" height="1572"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Eqk-0p-Ioj">
<rect key="frame" x="20" y="20" width="315" height="1532"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Bmg-VI-mjQ">
<rect key="frame" x="0.0" y="0.0" width="315" height="687"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="WiG-Qk-oxE">
<rect key="frame" x="0.0" y="0.0" width="315" height="25"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="id" translatesAutoresizingMaskIntoConstraints="NO" id="8KM-eS-7ma">
<rect key="frame" x="0.0" y="0.0" width="25" height="25"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="25" id="YNB-Pq-Zvt"/>
<constraint firstAttribute="width" constant="25" id="fzB-qS-lVG"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Personal Information" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dHG-rz-K0N">
<rect key="frame" x="30" y="0.0" width="285" height="25"/>
<constraints>
<constraint firstAttribute="height" constant="25" id="zeO-YM-y5G"/>
</constraints>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="19"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="OwE-Ab-N83">
<rect key="frame" x="0.0" y="30" width="315" height="416"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Employer Name" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="4Ht-H7-uZe" customClass="ValidationTextField" customModule="Fast_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="315" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Employer Name"/>
</userDefinedRuntimeAttributes>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Full Name (Shown in your id card)" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="SVD-OG-9os" customClass="ValidationTextField" customModule="Fast_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="53" width="315" height="45"/>
<constraints>
<constraint firstAttribute="height" constant="45" id="p5r-dd-bii"/>
</constraints>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="allCharacters" textContentType="name"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Select Source Of Fund"/>
</userDefinedRuntimeAttributes>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Gender" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="kXC-Oc-efk" customClass="ValidationTextField" customModule="Fast_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="106" width="315" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Monthly Income"/>
</userDefinedRuntimeAttributes>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Date of birth" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="0Lm-Yp-fcs" customClass="ValidationTextField" customModule="Fast_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="159" width="315" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits" keyboardType="numberPad"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Mobile Number"/>
</userDefinedRuntimeAttributes>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="City" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="hX6-tX-ygh" customClass="ValidationTextField" customModule="Fast_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="212" width="315" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Employee/Business Type"/>
</userDefinedRuntimeAttributes>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="E-mail" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="IsM-vf-1HP" customClass="ValidationTextField" customModule="Fast_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="265" width="315" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits" keyboardType="emailAddress"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Email Address"/>
</userDefinedRuntimeAttributes>
</textField>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Dto-Il-AZr">
<rect key="frame" x="0.0" y="318" width="315" height="45"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Address" textAlignment="natural" minimumFontSize="12" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="g6b-c1-elD" customClass="ValidationTextField" customModule="Fast_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="283" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Jrn-Np-285">
<rect key="frame" x="283" y="0.0" width="32" height="45"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="p8D-ri-Y0a">
<rect key="frame" x="5" y="13" width="25" height="25"/>
<constraints>
<constraint firstAttribute="height" constant="25" id="eZc-Pm-Uun"/>
<constraint firstAttribute="width" constant="25" id="jP2-kv-ZoD"/>
</constraints>
<color key="tintColor" name="ThemeRed"/>
<state key="normal" image="gps"/>
<connections>
<action selector="gpsButtonTapped:" destination="HSb-ou-7T5" eventType="touchUpInside" id="ntz-f5-p7K"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="p8D-ri-Y0a" firstAttribute="leading" secondItem="Jrn-Np-285" secondAttribute="leading" constant="5" id="HZP-9l-dAi"/>
<constraint firstAttribute="trailing" secondItem="p8D-ri-Y0a" secondAttribute="trailing" constant="2" id="OIx-PB-b04"/>
<constraint firstAttribute="bottom" secondItem="p8D-ri-Y0a" secondAttribute="bottom" constant="7" id="SXJ-z5-0T6"/>
<constraint firstItem="p8D-ri-Y0a" firstAttribute="top" secondItem="Jrn-Np-285" secondAttribute="top" constant="13" id="vhW-ho-eiw"/>
</constraints>
</view>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BkD-3R-Ve6">
<rect key="frame" x="0.0" y="371" width="315" height="45"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="RTH-Te-uwT">
<rect key="frame" x="0.0" y="451" width="315" height="25"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="id" translatesAutoresizingMaskIntoConstraints="NO" id="Fza-xS-5m3">
<rect key="frame" x="0.0" y="0.0" width="25" height="25"/>
<constraints>
<constraint firstAttribute="height" constant="25" id="bbf-3m-bKq"/>
<constraint firstAttribute="width" constant="25" id="uev-fw-SIb"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ID Information" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Cog-5g-LiE">
<rect key="frame" x="30" y="0.0" width="285" height="25"/>
<constraints>
<constraint firstAttribute="height" constant="25" id="MSL-o0-Nja"/>
</constraints>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="19"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="Di2-cd-lgJ">
<rect key="frame" x="0.0" y="481" width="315" height="151"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Full Name (Shown in your id card)" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="hEr-Pf-Iwt" customClass="ValidationTextField" customModule="Fast_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="315" height="45"/>
<constraints>
<constraint firstAttribute="height" constant="45" id="bYs-mZ-asI"/>
</constraints>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="allCharacters" textContentType="name"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Id Type"/>
</userDefinedRuntimeAttributes>
</textField>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="E-mail" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="MkR-sA-RxH" customClass="ValidationTextField" customModule="Fast_Remit" customModuleProvider="target">
<rect key="frame" x="0.0" y="53" width="315" height="45"/>
<color key="textColor" name="ThemeText"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isShowTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isUseTitle" value="NO"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isLineHidden" value="NO"/>
<userDefinedRuntimeAttribute type="color" keyPath="leftImageTintColor">
<color key="value" name="ThemeText"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="placeholder" value="Additional Id Type"/>
</userDefinedRuntimeAttributes>
</textField>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PJX-Fr-Jjo">
<rect key="frame" x="0.0" y="106" width="315" height="45"/>
<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="EE0-NK-Hdn">
<rect key="frame" x="0.0" y="637" width="315" height="50"/>
<color key="backgroundColor" name="ThemeRed"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="D00-1q-w5H"/>
</constraints>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="17"/>
<state key="normal" title="Save and Continue">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="SIj-Gb-xvD">
<rect key="frame" x="0.0" y="692" width="315" height="840"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="e7C-xN-Lnq">
<rect key="frame" x="0.0" y="0.0" width="315" height="25"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3FF-GV-btL">
<rect key="frame" x="0.0" y="0.0" width="25" height="25"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="picture" translatesAutoresizingMaskIntoConstraints="NO" id="dvp-ns-KlB">
<rect key="frame" x="2.5" y="2.5" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="N33-ZP-UPn"/>
<constraint firstAttribute="height" constant="20" id="kUH-lo-l8Y"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="dvp-ns-KlB" firstAttribute="top" secondItem="3FF-GV-btL" secondAttribute="top" constant="2.5" id="Hsw-AJ-ttT"/>
<constraint firstAttribute="trailing" secondItem="dvp-ns-KlB" secondAttribute="trailing" constant="2.5" id="UCC-6N-D83"/>
<constraint firstItem="dvp-ns-KlB" firstAttribute="leading" secondItem="3FF-GV-btL" secondAttribute="leading" constant="2.5" id="m9r-qU-OBO"/>
<constraint firstAttribute="bottom" secondItem="dvp-ns-KlB" secondAttribute="bottom" constant="2.5" id="phc-CF-3IH"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Your Face Picture" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1Qk-eY-RVJ">
<rect key="frame" x="30" y="0.0" width="285" height="25"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="19"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="PMC-6K-aRj">
<rect key="frame" x="0.0" y="45" width="315" height="94"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="elX-eZ-fB1">
<rect key="frame" x="0.0" y="0.0" width="315" height="94"/>
<subviews>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jAz-cy-mSO" userLabel="ViewFront">
<rect key="frame" x="0.0" y="0.0" width="315" height="94"/>
<subviews>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Rdm-cY-eIH">
<rect key="frame" x="2" y="2" width="98" height="90"/>
<subviews>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kDo-2B-xpO">
<rect key="frame" x="0.0" y="0.0" width="98" height="90"/>
<state key="normal" image="ic_passport_picture"/>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="kDo-2B-xpO" firstAttribute="top" secondItem="Rdm-cY-eIH" secondAttribute="top" id="2ZT-TJ-4nF"/>
<constraint firstAttribute="bottom" secondItem="kDo-2B-xpO" secondAttribute="bottom" id="74C-qc-uCk"/>
<constraint firstAttribute="trailing" secondItem="kDo-2B-xpO" secondAttribute="trailing" id="BFm-1a-hDT"/>
<constraint firstAttribute="width" constant="98" id="QVI-v0-XH0"/>
<constraint firstItem="kDo-2B-xpO" firstAttribute="leading" secondItem="Rdm-cY-eIH" secondAttribute="leading" id="bYm-tO-BD8"/>
</constraints>
</view>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qdK-Dw-nHt">
<rect key="frame" x="110" y="2" width="203" height="90"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="11" translatesAutoresizingMaskIntoConstraints="NO" id="vgU-wr-MyS">
<rect key="frame" x="0.0" y="19" width="203" height="52.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Your Face Picture" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RuL-lt-Ra8">
<rect key="frame" x="0.0" y="0.0" width="118.5" height="17.5"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="15"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="right" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Hd9-Ys-WuN">
<rect key="frame" x="0.0" y="28.5" width="58" height="24"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="10"/>
<state key="normal" title="View Sample">
<color key="titleColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="showSampleButton:" destination="HSb-ou-7T5" eventType="touchUpInside" id="5WS-pb-sbt"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="vgU-wr-MyS" firstAttribute="centerY" secondItem="qdK-Dw-nHt" secondAttribute="centerY" id="6ZD-dd-UFg"/>
<constraint firstItem="vgU-wr-MyS" firstAttribute="leading" secondItem="qdK-Dw-nHt" secondAttribute="leading" id="gru-P6-RE3"/>
<constraint firstItem="vgU-wr-MyS" firstAttribute="centerX" secondItem="qdK-Dw-nHt" secondAttribute="centerX" id="jxc-eU-Cn1"/>
<constraint firstAttribute="trailing" secondItem="vgU-wr-MyS" secondAttribute="trailing" id="wl1-JX-3dB"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="qdK-Dw-nHt" secondAttribute="trailing" constant="2" id="420-XA-34V"/>
<constraint firstItem="qdK-Dw-nHt" firstAttribute="leading" secondItem="Rdm-cY-eIH" secondAttribute="trailing" constant="10" id="ABM-sF-vn0"/>
<constraint firstAttribute="height" constant="94" id="DEJ-yT-2Zu"/>
<constraint firstAttribute="bottom" secondItem="Rdm-cY-eIH" secondAttribute="bottom" constant="2" id="Jjk-tB-MTg"/>
<constraint firstAttribute="bottom" secondItem="qdK-Dw-nHt" secondAttribute="bottom" constant="2" id="Mvk-rv-iyg"/>
<constraint firstItem="Rdm-cY-eIH" firstAttribute="leading" secondItem="jAz-cy-mSO" secondAttribute="leading" constant="2" id="hJe-MS-w9a"/>
<constraint firstItem="qdK-Dw-nHt" firstAttribute="top" secondItem="jAz-cy-mSO" secondAttribute="top" constant="2" id="oks-E8-RGB"/>
<constraint firstItem="Rdm-cY-eIH" firstAttribute="top" secondItem="jAz-cy-mSO" secondAttribute="top" constant="2" id="zD5-Xf-nDb"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="5"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="elX-eZ-fB1" firstAttribute="top" secondItem="PMC-6K-aRj" secondAttribute="top" id="9Y4-tJ-UMP"/>
<constraint firstAttribute="bottom" secondItem="elX-eZ-fB1" secondAttribute="bottom" id="CuF-uL-Yi8"/>
<constraint firstItem="elX-eZ-fB1" firstAttribute="leading" secondItem="PMC-6K-aRj" secondAttribute="leading" id="oAm-G6-BbV"/>
<constraint firstAttribute="trailing" secondItem="elX-eZ-fB1" secondAttribute="trailing" id="x0F-Cx-qYO"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="g5T-gO-2XU">
<rect key="frame" x="0.0" y="159" width="315" height="25"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zyi-hN-2EQ">
<rect key="frame" x="0.0" y="0.0" width="25" height="25"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="picture" translatesAutoresizingMaskIntoConstraints="NO" id="Vc7-fz-TGB">
<rect key="frame" x="2.5" y="2.5" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="Iv4-ed-tPw"/>
<constraint firstAttribute="height" constant="20" id="tlh-uL-ZNd"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Vc7-fz-TGB" firstAttribute="leading" secondItem="Zyi-hN-2EQ" secondAttribute="leading" constant="2.5" id="78Z-ww-r7K"/>
<constraint firstItem="Vc7-fz-TGB" firstAttribute="top" secondItem="Zyi-hN-2EQ" secondAttribute="top" constant="2.5" id="IQv-Ca-Rro"/>
<constraint firstAttribute="trailing" secondItem="Vc7-fz-TGB" secondAttribute="trailing" constant="2.5" id="ebR-eq-6ff"/>
<constraint firstAttribute="bottom" secondItem="Vc7-fz-TGB" secondAttribute="bottom" constant="2.5" id="roe-Lj-GTv"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Primary ID Documents" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RNe-jc-Qc8">
<rect key="frame" x="30" y="0.0" width="285" height="25"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="19"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="D5K-nv-4xv">
<rect key="frame" x="0.0" y="204" width="315" height="342"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="kn3-YB-OS0">
<rect key="frame" x="0.0" y="0.0" width="315" height="342"/>
<subviews>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="m8s-Gg-2jO" userLabel="ViewFront">
<rect key="frame" x="0.0" y="0.0" width="315" height="94"/>
<subviews>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wYj-gJ-Uck">
<rect key="frame" x="2" y="2" width="98" height="90"/>
<subviews>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EJu-if-oSE">
<rect key="frame" x="0.0" y="0.0" width="98" height="90"/>
<state key="normal" image="ic_passport_picture"/>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="EJu-if-oSE" secondAttribute="trailing" id="1yZ-qb-Yfl"/>
<constraint firstAttribute="width" constant="98" id="VIV-Yg-Uns"/>
<constraint firstAttribute="bottom" secondItem="EJu-if-oSE" secondAttribute="bottom" id="YxO-WE-iqf"/>
<constraint firstItem="EJu-if-oSE" firstAttribute="top" secondItem="wYj-gJ-Uck" secondAttribute="top" id="hec-5R-VhE"/>
<constraint firstItem="EJu-if-oSE" firstAttribute="leading" secondItem="wYj-gJ-Uck" secondAttribute="leading" id="kHI-5y-a3A"/>
</constraints>
</view>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Q3t-ZV-jUa">
<rect key="frame" x="110" y="2" width="203" height="90"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="11" translatesAutoresizingMaskIntoConstraints="NO" id="jWz-lo-vEP">
<rect key="frame" x="0.0" y="19" width="203" height="52.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Front ID" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bjj-F9-uG2">
<rect key="frame" x="0.0" y="0.0" width="54" height="17.5"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="15"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="right" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="l8F-WP-lmv">
<rect key="frame" x="0.0" y="28.5" width="58" height="24"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="10"/>
<state key="normal" title="View Sample">
<color key="titleColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="showSampleButton:" destination="HSb-ou-7T5" eventType="touchUpInside" id="hSe-00-z5W"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="jWz-lo-vEP" firstAttribute="centerY" secondItem="Q3t-ZV-jUa" secondAttribute="centerY" id="Hh0-au-COj"/>
<constraint firstAttribute="trailing" secondItem="jWz-lo-vEP" secondAttribute="trailing" id="gD0-UQ-IPB"/>
<constraint firstItem="jWz-lo-vEP" firstAttribute="centerX" secondItem="Q3t-ZV-jUa" secondAttribute="centerX" id="jOI-er-RYb"/>
<constraint firstItem="jWz-lo-vEP" firstAttribute="leading" secondItem="Q3t-ZV-jUa" secondAttribute="leading" id="m5j-io-6em"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="wYj-gJ-Uck" firstAttribute="leading" secondItem="m8s-Gg-2jO" secondAttribute="leading" constant="2" id="0kc-sa-7OV"/>
<constraint firstAttribute="trailing" secondItem="Q3t-ZV-jUa" secondAttribute="trailing" constant="2" id="GSH-60-92Y"/>
<constraint firstItem="wYj-gJ-Uck" firstAttribute="top" secondItem="m8s-Gg-2jO" secondAttribute="top" constant="2" id="GtI-GX-OiZ"/>
<constraint firstItem="Q3t-ZV-jUa" firstAttribute="top" secondItem="m8s-Gg-2jO" secondAttribute="top" constant="2" id="IEh-n4-eCW"/>
<constraint firstItem="Q3t-ZV-jUa" firstAttribute="leading" secondItem="wYj-gJ-Uck" secondAttribute="trailing" constant="10" id="ecM-O2-Mos"/>
<constraint firstAttribute="height" constant="94" id="l8G-ut-6OS"/>
<constraint firstAttribute="bottom" secondItem="Q3t-ZV-jUa" secondAttribute="bottom" constant="2" id="mfb-of-Hle"/>
<constraint firstAttribute="bottom" secondItem="wYj-gJ-Uck" secondAttribute="bottom" constant="2" id="phO-eg-NUD"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="5"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KUS-8w-FbG" userLabel="ViewBack">
<rect key="frame" x="0.0" y="124" width="315" height="94"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pT6-RT-2H5">
<rect key="frame" x="2" y="2" width="98" height="90"/>
<subviews>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KQ2-op-cWR">
<rect key="frame" x="0.0" y="0.0" width="98" height="90"/>
<state key="normal" image="ic_another_id_picture"/>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="KQ2-op-cWR" secondAttribute="trailing" id="KuB-cc-2f4"/>
<constraint firstAttribute="bottom" secondItem="KQ2-op-cWR" secondAttribute="bottom" id="Ofo-3O-tbZ"/>
<constraint firstItem="KQ2-op-cWR" firstAttribute="top" secondItem="pT6-RT-2H5" secondAttribute="top" id="Sdr-eR-q4U"/>
<constraint firstItem="KQ2-op-cWR" firstAttribute="leading" secondItem="pT6-RT-2H5" secondAttribute="leading" id="bGb-xO-HGh"/>
<constraint firstAttribute="width" constant="98" id="x7E-dE-oBz"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cbQ-gA-NRk">
<rect key="frame" x="110" y="2" width="203" height="90"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="nTK-7E-Rqg">
<rect key="frame" x="0.0" y="14.5" width="203" height="61"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Back ID" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Srj-TC-O06">
<rect key="frame" x="0.0" y="0.0" width="53" height="35"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="35" id="FGP-JA-w2F"/>
</constraints>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="15"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="1" contentMode="scaleToFill" contentHorizontalAlignment="right" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ads-XP-HXa">
<rect key="frame" x="0.0" y="37" width="58" height="24"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="10"/>
<state key="normal" title="View Sample">
<color key="titleColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="showSampleButton:" destination="HSb-ou-7T5" eventType="touchUpInside" id="kEV-J4-JPE"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="nTK-7E-Rqg" secondAttribute="trailing" id="QEa-1a-BG0"/>
<constraint firstItem="nTK-7E-Rqg" firstAttribute="centerX" secondItem="cbQ-gA-NRk" secondAttribute="centerX" id="hAh-Z4-DRZ"/>
<constraint firstItem="nTK-7E-Rqg" firstAttribute="leading" secondItem="cbQ-gA-NRk" secondAttribute="leading" id="hDX-Hf-giN"/>
<constraint firstItem="nTK-7E-Rqg" firstAttribute="centerY" secondItem="cbQ-gA-NRk" secondAttribute="centerY" id="xZX-K2-obA"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="pT6-RT-2H5" secondAttribute="bottom" constant="2" id="9d8-E6-FMJ"/>
<constraint firstItem="pT6-RT-2H5" firstAttribute="leading" secondItem="KUS-8w-FbG" secondAttribute="leading" constant="2" id="I2D-ww-cqP"/>
<constraint firstItem="cbQ-gA-NRk" firstAttribute="leading" secondItem="pT6-RT-2H5" secondAttribute="trailing" constant="10" id="Mgp-ix-Z5d"/>
<constraint firstAttribute="trailing" secondItem="cbQ-gA-NRk" secondAttribute="trailing" constant="2" id="NRe-4f-faG"/>
<constraint firstItem="cbQ-gA-NRk" firstAttribute="top" secondItem="KUS-8w-FbG" secondAttribute="top" constant="2" id="UUa-C4-MyN"/>
<constraint firstItem="pT6-RT-2H5" firstAttribute="top" secondItem="KUS-8w-FbG" secondAttribute="top" constant="2" id="hEa-sI-il2"/>
<constraint firstAttribute="height" constant="94" id="lKl-FG-Xmk"/>
<constraint firstAttribute="bottom" secondItem="cbQ-gA-NRk" secondAttribute="bottom" constant="2" id="rC4-VE-Me4"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="5"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NR2-z2-DOA" userLabel="ViewBack">
<rect key="frame" x="0.0" y="248" width="315" height="94"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="AsK-Nf-df1">
<rect key="frame" x="2" y="2" width="98" height="90"/>
<subviews>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Zyf-eU-YL6">
<rect key="frame" x="0.0" y="0.0" width="98" height="90"/>
<state key="normal" image="ic_another_id_picture"/>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="Zyf-eU-YL6" secondAttribute="trailing" id="III-Vk-b1D"/>
<constraint firstAttribute="width" constant="98" id="MMr-sJ-cKi"/>
<constraint firstItem="Zyf-eU-YL6" firstAttribute="leading" secondItem="AsK-Nf-df1" secondAttribute="leading" id="Wdz-DC-sld"/>
<constraint firstItem="Zyf-eU-YL6" firstAttribute="top" secondItem="AsK-Nf-df1" secondAttribute="top" id="cuq-EJ-0pB"/>
<constraint firstAttribute="bottom" secondItem="Zyf-eU-YL6" secondAttribute="bottom" id="dLR-2N-pS0"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5fu-2V-Eb2">
<rect key="frame" x="110" y="2" width="203" height="90"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="Tsu-XM-MRp">
<rect key="frame" x="0.0" y="14.5" width="203" height="61"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Side ID" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Xjo-Gi-RHq">
<rect key="frame" x="0.0" y="0.0" width="49" height="35"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="35" id="5V1-vL-gJa"/>
</constraints>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="15"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="1" contentMode="scaleToFill" contentHorizontalAlignment="right" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wYc-6F-9AB">
<rect key="frame" x="0.0" y="37" width="58" height="24"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="10"/>
<state key="normal" title="View Sample">
<color key="titleColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="showSampleButton:" destination="HSb-ou-7T5" eventType="touchUpInside" id="L86-Ke-6ky"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="Tsu-XM-MRp" secondAttribute="trailing" id="0ai-GJ-yyG"/>
<constraint firstItem="Tsu-XM-MRp" firstAttribute="centerY" secondItem="5fu-2V-Eb2" secondAttribute="centerY" id="9Ca-TC-8Tu"/>
<constraint firstItem="Tsu-XM-MRp" firstAttribute="leading" secondItem="5fu-2V-Eb2" secondAttribute="leading" id="Tlk-J8-IbD"/>
<constraint firstItem="Tsu-XM-MRp" firstAttribute="centerX" secondItem="5fu-2V-Eb2" secondAttribute="centerX" id="jW3-BF-FAO"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="5fu-2V-Eb2" secondAttribute="bottom" constant="2" id="DG5-22-bu0"/>
<constraint firstAttribute="trailing" secondItem="5fu-2V-Eb2" secondAttribute="trailing" constant="2" id="IKk-lE-pMp"/>
<constraint firstAttribute="height" constant="94" id="K2V-IS-rRm"/>
<constraint firstItem="AsK-Nf-df1" firstAttribute="top" secondItem="NR2-z2-DOA" secondAttribute="top" constant="2" id="OS4-bg-ltt"/>
<constraint firstItem="5fu-2V-Eb2" firstAttribute="leading" secondItem="AsK-Nf-df1" secondAttribute="trailing" constant="10" id="RkJ-rs-OPo"/>
<constraint firstItem="5fu-2V-Eb2" firstAttribute="top" secondItem="NR2-z2-DOA" secondAttribute="top" constant="2" id="acK-nj-QWc"/>
<constraint firstItem="AsK-Nf-df1" firstAttribute="leading" secondItem="NR2-z2-DOA" secondAttribute="leading" constant="2" id="doq-yz-ce6"/>
<constraint firstAttribute="bottom" secondItem="AsK-Nf-df1" secondAttribute="bottom" constant="2" id="loe-Hx-56J"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="5"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="kn3-YB-OS0" secondAttribute="trailing" id="ZLq-3K-guJ"/>
<constraint firstItem="kn3-YB-OS0" firstAttribute="leading" secondItem="D5K-nv-4xv" secondAttribute="leading" id="hJ0-tL-X7N"/>
<constraint firstAttribute="bottom" secondItem="kn3-YB-OS0" secondAttribute="bottom" id="hj1-CD-iqL"/>
<constraint firstItem="kn3-YB-OS0" firstAttribute="top" secondItem="D5K-nv-4xv" secondAttribute="top" id="yMU-5Q-ZAX"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="dz6-Ov-vmR">
<rect key="frame" x="0.0" y="566" width="315" height="25"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8EX-Kp-2q9">
<rect key="frame" x="0.0" y="0.0" width="25" height="25"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="picture" translatesAutoresizingMaskIntoConstraints="NO" id="3Ha-K2-EiL">
<rect key="frame" x="2.5" y="2.5" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="0Pd-7X-Cf0"/>
<constraint firstAttribute="height" constant="20" id="EKE-WH-xhy"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="3Ha-K2-EiL" firstAttribute="top" secondItem="8EX-Kp-2q9" secondAttribute="top" constant="2.5" id="LMa-RW-u9n"/>
<constraint firstItem="3Ha-K2-EiL" firstAttribute="leading" secondItem="8EX-Kp-2q9" secondAttribute="leading" constant="2.5" id="Mif-Gp-CPj"/>
<constraint firstAttribute="bottom" secondItem="3Ha-K2-EiL" secondAttribute="bottom" constant="2.5" id="RUp-Cg-IVQ"/>
<constraint firstAttribute="trailing" secondItem="3Ha-K2-EiL" secondAttribute="trailing" constant="2.5" id="t4u-cR-m1Z"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Additional ID Documents" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="60Q-Qk-qGc">
<rect key="frame" x="30" y="0.0" width="285" height="25"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="19"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wJY-To-abc">
<rect key="frame" x="0.0" y="611" width="315" height="94"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="Uze-1a-gUa">
<rect key="frame" x="0.0" y="0.0" width="315" height="94"/>
<subviews>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Oh1-UA-AVd" userLabel="ViewFront">
<rect key="frame" x="0.0" y="0.0" width="315" height="94"/>
<subviews>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6Oj-J7-xSf">
<rect key="frame" x="2" y="2" width="98" height="90"/>
<subviews>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1ap-cT-HAO">
<rect key="frame" x="0.0" y="0.0" width="98" height="90"/>
<state key="normal" image="ic_passport_picture"/>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="1ap-cT-HAO" firstAttribute="leading" secondItem="6Oj-J7-xSf" secondAttribute="leading" id="BkQ-8g-mk9"/>
<constraint firstItem="1ap-cT-HAO" firstAttribute="top" secondItem="6Oj-J7-xSf" secondAttribute="top" id="Fb3-WK-Agn"/>
<constraint firstAttribute="bottom" secondItem="1ap-cT-HAO" secondAttribute="bottom" id="OI3-gh-QLJ"/>
<constraint firstAttribute="trailing" secondItem="1ap-cT-HAO" secondAttribute="trailing" id="RJb-i9-ZCm"/>
<constraint firstAttribute="width" constant="98" id="aGX-dx-LLF"/>
</constraints>
</view>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cVx-Ot-ALo">
<rect key="frame" x="110" y="2" width="203" height="90"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="11" translatesAutoresizingMaskIntoConstraints="NO" id="TdD-O4-xXg">
<rect key="frame" x="0.0" y="19" width="203" height="52.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Additional ID" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9Ye-vp-Vy5">
<rect key="frame" x="0.0" y="0.0" width="86" height="17.5"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="15"/>
<color key="textColor" name="ThemeText"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="right" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lY3-Do-yEX">
<rect key="frame" x="0.0" y="28.5" width="58" height="24"/>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Regular" family="San Francisco Display" pointSize="10"/>
<state key="normal" title="View Sample">
<color key="titleColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="showSampleButton:" destination="HSb-ou-7T5" eventType="touchUpInside" id="vXa-qB-PhC"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="TdD-O4-xXg" firstAttribute="centerX" secondItem="cVx-Ot-ALo" secondAttribute="centerX" id="3CS-6W-pau"/>
<constraint firstItem="TdD-O4-xXg" firstAttribute="leading" secondItem="cVx-Ot-ALo" secondAttribute="leading" id="6Pv-7v-UeA"/>
<constraint firstAttribute="trailing" secondItem="TdD-O4-xXg" secondAttribute="trailing" id="mLY-ub-tsb"/>
<constraint firstItem="TdD-O4-xXg" firstAttribute="centerY" secondItem="cVx-Ot-ALo" secondAttribute="centerY" id="mlf-io-7p0"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="cVx-Ot-ALo" secondAttribute="bottom" constant="2" id="9G0-NR-e4c"/>
<constraint firstAttribute="height" constant="94" id="Jfj-TA-9jk"/>
<constraint firstItem="6Oj-J7-xSf" firstAttribute="top" secondItem="Oh1-UA-AVd" secondAttribute="top" constant="2" id="Md3-si-kv8"/>
<constraint firstAttribute="bottom" secondItem="6Oj-J7-xSf" secondAttribute="bottom" constant="2" id="ZEc-9M-1fi"/>
<constraint firstItem="cVx-Ot-ALo" firstAttribute="leading" secondItem="6Oj-J7-xSf" secondAttribute="trailing" constant="10" id="iXl-Fi-4Yo"/>
<constraint firstAttribute="trailing" secondItem="cVx-Ot-ALo" secondAttribute="trailing" constant="2" id="qfd-8a-kLB"/>
<constraint firstItem="6Oj-J7-xSf" firstAttribute="leading" secondItem="Oh1-UA-AVd" secondAttribute="leading" constant="2" id="sPK-76-4nt"/>
<constraint firstItem="cVx-Ot-ALo" firstAttribute="top" secondItem="Oh1-UA-AVd" secondAttribute="top" constant="2" id="uXt-rA-Kbf"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<integer key="value" value="5"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Uze-1a-gUa" firstAttribute="top" secondItem="wJY-To-abc" secondAttribute="top" id="Lt6-Of-P69"/>
<constraint firstAttribute="bottom" secondItem="Uze-1a-gUa" secondAttribute="bottom" id="VOo-t0-MS3"/>
<constraint firstAttribute="trailing" secondItem="Uze-1a-gUa" secondAttribute="trailing" id="gqR-6d-bt8"/>
<constraint firstItem="Uze-1a-gUa" firstAttribute="leading" secondItem="wJY-To-abc" secondAttribute="leading" id="wIM-1o-oNr"/>
</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="gNe-Qu-6aB">
<rect key="frame" x="0.0" y="725" width="315" height="50"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QBC-Fu-PsV">
<rect key="frame" x="0.0" y="795" width="315" height="45"/>
<color key="backgroundColor" name="ThemeRed"/>
<constraints>
<constraint firstAttribute="height" constant="45" id="0FB-Ok-i85"/>
</constraints>
<fontDescription key="fontDescription" name="SanFranciscoDisplay-Medium" family="San Francisco Display" pointSize="17"/>
<state key="normal" title="Save and Next">
<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 firstAttribute="bottom" secondItem="Eqk-0p-Ioj" secondAttribute="bottom" constant="20" id="Vz2-ak-4ek"/>
<constraint firstAttribute="trailing" secondItem="Eqk-0p-Ioj" secondAttribute="trailing" constant="20" id="cpz-xI-a8q"/>
<constraint firstItem="Eqk-0p-Ioj" firstAttribute="top" secondItem="YV6-LS-yFu" secondAttribute="top" constant="20" id="fHc-Os-q3o"/>
<constraint firstItem="Eqk-0p-Ioj" firstAttribute="leading" secondItem="YV6-LS-yFu" secondAttribute="leading" constant="20" id="fIq-Vq-4oV"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="YV6-LS-yFu" secondAttribute="trailing" constant="10" id="HJG-Cm-9pp"/>
<constraint firstAttribute="bottom" secondItem="YV6-LS-yFu" secondAttribute="bottom" constant="10" id="ZJt-e4-7Ry"/>
<constraint firstItem="YV6-LS-yFu" firstAttribute="leading" secondItem="TF6-Vy-Vuj" secondAttribute="leading" constant="10" id="i2c-IP-LJy"/>
<constraint firstItem="YV6-LS-yFu" firstAttribute="top" secondItem="TF6-Vy-Vuj" secondAttribute="top" constant="10" id="xSc-R5-WKV"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="TF6-Vy-Vuj" secondAttribute="bottom" id="7Lh-04-a52"/>
<constraint firstItem="TF6-Vy-Vuj" firstAttribute="width" secondItem="HAO-EE-YnY" secondAttribute="width" id="Aag-bR-hw1"/>
<constraint firstItem="TF6-Vy-Vuj" firstAttribute="top" secondItem="HAO-EE-YnY" secondAttribute="top" id="RUK-NJ-GMn"/>
<constraint firstItem="TF6-Vy-Vuj" firstAttribute="leading" secondItem="HAO-EE-YnY" secondAttribute="leading" id="b1q-HN-SnL"/>
<constraint firstAttribute="trailing" secondItem="TF6-Vy-Vuj" secondAttribute="trailing" id="teC-17-xfO"/>
</constraints>
</scrollView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="HAO-EE-YnY" secondAttribute="bottom" id="OgU-Jp-gFZ"/>
<constraint firstItem="HAO-EE-YnY" firstAttribute="leading" secondItem="9Uc-9s-KgO" secondAttribute="leading" id="aN8-2L-cch"/>
<constraint firstAttribute="trailing" secondItem="HAO-EE-YnY" secondAttribute="trailing" id="deo-3y-Kxw"/>
<constraint firstItem="HAO-EE-YnY" firstAttribute="top" secondItem="y1H-iV-BwG" secondAttribute="bottom" id="xKs-zL-zEa"/>
</constraints>
</view>
<size key="freeformSize" width="375" height="1700"/>
<connections>
<outlet property="additionalIDContainer" destination="wJY-To-abc" id="hDR-he-gMv"/>
<outlet property="additionalIdButton" destination="1ap-cT-HAO" id="m3F-Ms-3UF"/>
<outlet property="additionalIdSample" destination="lY3-Do-yEX" id="ZPd-dD-PKO"/>
<outlet property="additionalIdType" destination="MkR-sA-RxH" id="tYF-rr-BcO"/>
<outlet property="address" destination="g6b-c1-elD" id="GrC-PX-mDf"/>
<outlet property="backIDContainer" destination="KUS-8w-FbG" id="63m-B3-fob"/>
<outlet property="backIdButton" destination="KQ2-op-cWR" id="bzS-Yr-ogk"/>
<outlet property="backIdSample" destination="ads-XP-HXa" id="flx-4q-1sI"/>
<outlet property="businessType" destination="hX6-tX-ygh" id="zFI-C3-JBB"/>
<outlet property="emailAddress" destination="IsM-vf-1HP" id="cad-yn-b4z"/>
<outlet property="employerName" destination="4Ht-H7-uZe" id="a52-xn-3d4"/>
<outlet property="facePicSampleBttn" destination="Hd9-Ys-WuN" id="tEz-ih-QXC"/>
<outlet property="facePictureButton" destination="kDo-2B-xpO" id="SWi-Wb-l6g"/>
<outlet property="facePictureContainer" destination="PMC-6K-aRj" id="YpJ-7v-3Bd"/>
<outlet property="frontIDContainer" destination="m8s-Gg-2jO" id="Ia8-IA-JYY"/>
<outlet property="frontIdButton" destination="EJu-if-oSE" id="7AS-NX-s6o"/>
<outlet property="frontIdSample" destination="l8F-WP-lmv" id="Oit-D7-PIC"/>
<outlet property="gpsButton" destination="p8D-ri-Y0a" id="xpj-Hv-9Ut"/>
<outlet property="idType" destination="hEr-Pf-Iwt" id="Mtx-0W-uo8"/>
<outlet property="mobileNumber" destination="0Lm-Yp-fcs" id="7TZ-gs-2hK"/>
<outlet property="monthlyIncome" destination="kXC-Oc-efk" id="fhg-Tt-2t5"/>
<outlet property="personalInfoSaveBttn" destination="EE0-NK-Hdn" id="ZqY-04-aO1"/>
<outlet property="personalInformationStack" destination="Bmg-VI-mjQ" id="0Vo-lv-VoU"/>
<outlet property="pictureSaveBttn" destination="QBC-Fu-PsV" id="46X-4W-BJY"/>
<outlet property="pictureUploadStack" destination="SIj-Gb-xvD" id="rwG-rk-hDt"/>
<outlet property="sideIDContainer" destination="NR2-z2-DOA" id="18Z-yu-4LY"/>
<outlet property="sideIdButton" destination="Zyf-eU-YL6" id="rBQ-BV-AB4"/>
<outlet property="sideIdSample" destination="wYc-6F-9AB" id="a2y-XQ-Cee"/>
<outlet property="sourceOfFund" destination="SVD-OG-9os" id="Ale-WC-rvy"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="8je-5K-XuW" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-91" y="233"/>
</scene>
</scenes>
<resources>
<image name="gps" width="256" height="256"/>
<image name="ic_another_id_picture" width="256" height="256"/>
<image name="ic_passport_picture" width="256" height="256"/>
<image name="id" width="256" height="256"/>
<image name="picture" width="16" height="16"/>
<namedColor name="ThemeRed">
<color red="0.92941176470588238" green="0.10588235294117647" blue="0.14117647058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<namedColor name="ThemeText">
<color red="0.28999999165534973" green="0.28999999165534973" blue="0.28999999165534973" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
</resources>
<color key="tintColor" red="0.78177064659999995" green="0.55228364470000002" blue="0.018981300289999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</document>

717
GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/User Interface/View/ExistingUserKycViewController.swift

@ -0,0 +1,717 @@
//
// ExistingUserKycViewController.swift
// GME Remit
//
// Created by Shiran on 8/18/20.
//Copyright © 2020 Gobal Money Express Co. Ltd. All rights reserved.
//
import UIKit
import RxSwift
import RxCocoa
import CoreLocation
import PMAlertController
import Kingfisher
class ExistingUserKycViewController: UIViewController {
private enum PhotoType: Int {
case frontID
case backID
case sideID
case facePicture
case anotherID
}
var step: NewRegisterViewController.Step = .first
var isFirst: Bool = true
// MARK: Properties
var presenter: ExistingUserKycPresenter!
weak var delegate: NewRegisterDelegate?
private let disposeBag = DisposeBag()
private let sendLocation = PublishSubject<CLLocation>()
private let locationManager = CLLocationManager()
private var photoType = PhotoType.frontID
private var multiMediaManager: MultiMediaManager?
private var imageCropper: ImageCroper?
private let frontIDImageTrigger = BehaviorSubject<String?>(value: nil)
private let backIDImageTrigger = BehaviorSubject<String?>(value: nil)
private let sideIDImageTrigger = BehaviorSubject<String?>(value: nil)
private let faceImageTrigger = BehaviorSubject<String?>(value: nil)
private let anotherIDImageTrigger = BehaviorSubject<String?>(value: nil)
private let frontImageBase64 = BehaviorSubject<String?>(value: nil)
private let backIDImageBase64 = BehaviorSubject<String?>(value: nil)
private let sideIDImageBase64 = BehaviorSubject<String?>(value: nil)
private let faceImageBase64 = BehaviorSubject<String?>(value: nil)
private let anotherIDImageBase64 = BehaviorSubject<String?>(value: nil)
private var isForeigner = true
// MARK: IBOutlets
@IBOutlet weak var employerName: ValidationTextField!
@IBOutlet weak var sourceOfFund: ValidationTextField!
@IBOutlet weak var monthlyIncome: ValidationTextField!
@IBOutlet weak var mobileNumber: ValidationTextField!
@IBOutlet weak var businessType: ValidationTextField!
@IBOutlet weak var emailAddress: ValidationTextField!
@IBOutlet weak var address: ValidationTextField!
@IBOutlet weak var idType: ValidationTextField!
@IBOutlet weak var additionalIdType: ValidationTextField!
@IBOutlet weak var gpsButton: UIButton!
@IBOutlet weak var personalInfoSaveBttn: UIButton!
@IBOutlet weak var pictureSaveBttn: UIButton!
@IBOutlet weak var personalInformationStack: UIStackView!
@IBOutlet weak var pictureUploadStack: UIStackView!
@IBOutlet weak var facePictureContainer: UIView!
@IBOutlet weak var frontIDContainer: UIView!
@IBOutlet weak var backIDContainer: UIView!
@IBOutlet weak var sideIDContainer: UIView!
@IBOutlet weak var additionalIDContainer: UIView!
@IBOutlet weak var facePicSampleBttn: UIButton!
@IBOutlet weak var frontIdSample: UIButton!
@IBOutlet weak var backIdSample: UIButton!
@IBOutlet weak var sideIdSample: UIButton!
@IBOutlet weak var additionalIdSample: UIButton!
@IBOutlet weak var facePictureButton: UIButton!
@IBOutlet weak var frontIdButton: UIButton!
@IBOutlet weak var backIdButton: UIButton!
@IBOutlet weak var sideIdButton: UIButton!
@IBOutlet weak var additionalIdButton: UIButton!
// MARK: VC's Life cycle
override func viewDidLoad() {
super.viewDidLoad()
self.isFirst = (self.step == .first)
setup()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.personalInformationStack.isHidden = self.step != .first
self.pictureUploadStack.isHidden = self.step == .first
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}
override func willMove(toParent parent: UIViewController?) {
if parent != nil {
viewWillAppear(true)
} else {
viewWillDisappear(true)
}
}
override func didMove(toParent parent: UIViewController?) {
if parent != nil {
viewDidAppear(true)
} else {
viewDidDisappear(true)
}
}
// MARK: IBActions
@IBAction func gpsButtonTapped(_ sender: UIButton) {
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
showProgressHud()
}
}
@IBAction func showSampleButton(_ sender: UIButton) {
guard let type = PhotoType(rawValue: sender.tag) else {return}
showSample(type: type)
}
private func showSample(type: PhotoType) {
let image: UIImage?
switch type {
case .frontID:
image = #imageLiteral(resourceName: "samplePassport")
case .backID:
image = #imageLiteral(resourceName: "sampleFront")
case .sideID:
image = #imageLiteral(resourceName: "sampleFront")
case .facePicture:
image = #imageLiteral(resourceName: "sampleFront")
case .anotherID:
image = #imageLiteral(resourceName: "sampleFront")
}
// show alert
let alertVC = PMAlertController(title: "", description: "", image: image, style: .alert)
alertVC.alertView.layer.cornerRadius = 5
let action = PMAlertAction(title: "ok_text".localized(), style: .cancel)
alertVC.addAction(action)
alertVC.modalPresentationStyle = .overFullScreen
self.present(alertVC, animated: true, completion: nil)
}
// MARK: Other Functions
private func setup() {
multiMediaManager = MultiMediaManager(presenter: self)
multiMediaManager?.delegate = self
imageCropper = ImageCroper(presentingViewController: self)
imageCropper?.delegate = self
setUI()
setBinding()
setUIBinding()
}
private func setUI() {
setMultiLanguages()
/*
personalInformationGroupImageView.setRenderingMode(with: .themeText)
idInformationGroupImageView.setRenderingMode(with: .themeText)
facePictureGroupImageView.setRenderingMode(with: .themeText)
primaryInfoDocumentImageView.setRenderingMode(with: .themeText)
additionalIDImageView.setRenderingMode(with: .themeText)
*/
sourceOfFund.useAsDropDown(items: nil)
monthlyIncome.useAsDropDown(items: nil)
businessType.useAsDropDown(items: nil)
idType.useAsDropDown(items: nil)
additionalIdType.useAsDropDown(items: nil)
personalInfoSaveBttn.layer.cornerRadius = 5
pictureSaveBttn.layer.cornerRadius = 5
additionalIdButton.layer.cornerRadius = 5
additionalIdButton.layer.borderWidth = 1
additionalIdButton.layer.borderColor = UIColor.themeText.cgColor
facePictureButton.layer.cornerRadius = 5
facePictureButton.layer.borderWidth = 1
facePictureButton.layer.borderColor = UIColor.themeText.cgColor
frontIdButton.layer.cornerRadius = 5
frontIdButton.layer.borderWidth = 1
frontIdButton.layer.borderColor = UIColor.themeText.cgColor
backIdButton.layer.cornerRadius = 5
backIdButton.layer.borderWidth = 1
backIdButton.layer.borderColor = UIColor.themeText.cgColor
sideIdButton.layer.cornerRadius = 5
sideIdButton.layer.borderWidth = 1
sideIdButton.layer.borderColor = UIColor.themeText.cgColor
employerName.validCondition = {!$0.isEmpty}
sourceOfFund.validCondition = {!$0.isEmpty}
monthlyIncome.validCondition = {!$0.isEmpty}
mobileNumber.validCondition = {!$0.isEmpty && $0.count > 8}
businessType.validCondition = {!$0.isEmpty}
emailAddress.validCondition = {$0.isEmail()}
address.validCondition = {!$0.isEmpty && $0.count < 50}
idType.validCondition = {!$0.isEmpty}
additionalIdType.validCondition = {!$0.isEmpty}
}
private func setUIBinding() {
frontIdButton.rx.tap.bind {[weak self] in
self?.photoType = .frontID
self?.multiMediaManager?.openPicker(mode: UIImagePickerController.CameraCaptureMode.photo)
}.disposed(by: disposeBag)
additionalIdButton.rx.tap.bind {[weak self] in
self?.photoType = .anotherID
self?.multiMediaManager?.openPicker(mode: UIImagePickerController.CameraCaptureMode.photo)
}.disposed(by: disposeBag)
backIdButton.rx.tap.bind {[weak self] in
self?.photoType = .backID
self?.multiMediaManager?.openPicker(mode: UIImagePickerController.CameraCaptureMode.photo)
}.disposed(by: disposeBag)
sideIdButton.rx.tap.bind {[weak self] in
self?.photoType = .sideID
self?.multiMediaManager?.openPicker(mode: UIImagePickerController.CameraCaptureMode.photo)
}.disposed(by: disposeBag)
facePictureButton.rx.tap.bind {[weak self] in
self?.photoType = .facePicture
self?.multiMediaManager?.openPicker(mode: UIImagePickerController.CameraCaptureMode.photo)
}.disposed(by: disposeBag)
frontIDImageTrigger
.asDriverOnErrorJustComplete()
.drive(onNext: {[weak self] in
if let imageData = $0 {
if let dataDecoded = Data(base64Encoded: imageData, options: .ignoreUnknownCharacters) {
DispatchQueue.main.async {
self?.frontIdButton.setImage(UIImage(data: dataDecoded), for: .normal)
self?.frontIdButton.addBlur()
self?.hideBorder(view: self?.frontIDContainer)
self?.frontImageBase64.onNext(imageData)
}
} else if let url = URL(string: imageData) {
DispatchQueue.main.async {
self?.showProgressHud()
self?.frontIdButton.kf.setImage(with: url, for: .normal) { result in
self?.hideProgressHud()
switch result {
case .success(let value):
self?.frontImageBase64.onNext(value.image.toBase64())
case .failure(let error):
print("Job failed: \(error.localizedDescription)")
}
}
self?.frontIdButton.addBlur()
self?.hideBorder(view: self?.frontIDContainer)
}
}
} else {
self?.frontImageBase64.onNext(nil)
self?.frontIdButton.setImage(UIImage(named: "ic_passport_picture"), for: .normal)
}
}).disposed(by: disposeBag)
backIDImageTrigger
.asDriverOnErrorJustComplete()
.drive(onNext: {[weak self] in
if let imageData = $0 {
if let dataDecoded = Data(base64Encoded: imageData, options: .ignoreUnknownCharacters) {
DispatchQueue.main.async {
self?.backIdButton.setImage(UIImage(data: dataDecoded), for: .normal)
self?.backIdButton.addBlur()
self?.hideBorder(view: self?.backIDContainer)
self?.backIDImageBase64.onNext(imageData)
}
} else if let url = URL(string: imageData) {
DispatchQueue.main.async {
self?.showProgressHud()
self?.backIdButton.kf.setImage(with: url, for: .normal) { result in
self?.hideProgressHud()
switch result {
case .success(let value):
self?.backIDImageBase64.onNext(value.image.toBase64())
case .failure(let error):
print("Job failed: \(error.localizedDescription)")
}
}
self?.backIdButton.addBlur()
self?.hideBorder(view: self?.backIDContainer)
}
}
} else {
self?.backIDImageBase64.onNext(nil)
self?.backIdButton.setImage(UIImage(named: "ic_passport_picture"), for: .normal)
}
}).disposed(by: disposeBag)
anotherIDImageTrigger
.asDriverOnErrorJustComplete()
.drive(onNext: {[weak self] in
if let imageData = $0 {
if let dataDecoded = Data(base64Encoded: imageData, options: .ignoreUnknownCharacters) {
DispatchQueue.main.async {
self?.additionalIdButton.setImage(UIImage(data: dataDecoded), for: .normal)
self?.additionalIdButton.addBlur()
self?.hideBorder(view: self?.additionalIDContainer)
self?.anotherIDImageBase64.onNext(imageData)
}
} else if let url = URL(string: imageData) {
DispatchQueue.main.async {
self?.showProgressHud()
self?.additionalIdButton.kf.setImage(with: url, for: .normal) { result in
self?.hideProgressHud()
switch result {
case .success(let value):
self?.anotherIDImageBase64.onNext(value.image.toBase64())
case .failure(let error):
print("Job failed: \(error.localizedDescription)")
}
}
self?.additionalIdButton.addBlur()
self?.hideBorder(view: self?.additionalIDContainer)
}
}
} else {
self?.anotherIDImageBase64.onNext(nil)
self?.additionalIdButton.setImage(UIImage(named: "ic_another_id_picture"), for: .normal)
}
}).disposed(by: disposeBag)
sideIDImageTrigger
.asDriverOnErrorJustComplete()
.drive(onNext: {[weak self] in
if let imageData = $0 {
if let dataDecoded = Data(base64Encoded: imageData, options: .ignoreUnknownCharacters) {
DispatchQueue.main.async {
self?.sideIdButton.setImage(UIImage(data: dataDecoded), for: .normal)
self?.sideIdButton.addBlur()
self?.hideBorder(view: self?.sideIDContainer)
self?.sideIDImageBase64.onNext(imageData)
}
} else if let url = URL(string: imageData) {
DispatchQueue.main.async {
self?.showProgressHud()
self?.sideIdButton.kf.setImage(with: url, for: .normal) { result in
self?.hideProgressHud()
switch result {
case .success(let value):
self?.sideIDImageBase64.onNext(value.image.toBase64())
case .failure(let error):
print("Job failed: \(error.localizedDescription)")
}
}
self?.sideIdButton.addBlur()
self?.hideBorder(view: self?.sideIDContainer)
}
}
} else {
self?.sideIDImageBase64.onNext(nil)
self?.sideIdButton.setImage(UIImage(named: "ic_passport_picture"), for: .normal)
}
}).disposed(by: disposeBag)
faceImageTrigger
.asDriverOnErrorJustComplete()
.drive(onNext: {[weak self] in
if let imageData = $0 {
if let dataDecoded = Data(base64Encoded: imageData, options: .ignoreUnknownCharacters) {
DispatchQueue.main.async {
self?.facePictureButton.setImage(UIImage(data: dataDecoded), for: .normal)
self?.facePictureButton.addBlur()
self?.hideBorder(view: self?.facePictureContainer)
self?.faceImageBase64.onNext(imageData)
}
} else if let url = URL(string: imageData) {
DispatchQueue.main.async {
self?.showProgressHud()
self?.facePictureButton.kf.setImage(with: url, for: .normal) { result in
self?.hideProgressHud()
switch result {
case .success(let value):
self?.faceImageBase64.onNext(value.image.toBase64())
case .failure(let error):
print("Job failed: \(error.localizedDescription)")
}
}
self?.facePictureButton.addBlur()
self?.hideBorder(view: self?.facePictureContainer)
}
}
} else {
self?.faceImageBase64.onNext(nil)
self?.facePictureButton.setImage(UIImage(named: "ic_passport_picture"), for: .normal)
}
}).disposed(by: disposeBag)
emailAddress.rx.filterBy(.alphabetNumbericSpecial).disposed(by: disposeBag)
address.rx.filterBy(.alphabet, isUppercase: true).disposed(by: disposeBag)
}
private func setBinding() {
let viewWillAppear = rx.sentMessage(#selector(UIViewController.viewWillAppear(_:))).map{_ in self.step == .first && self.isFirst}.asDriverOnErrorJustComplete()
let isValidPersonalInfo = Observable.combineLatest(
[
emailAddress.valid,
address.valid,
employerName.valid,
mobileNumber.valid,
sourceOfFund.valid,
monthlyIncome.valid,
businessType.valid,
idType.valid,
additionalIdType.valid
]
).map { $0.allSatisfy { $0 } }
.distinctUntilChanged()
let isValidPictures = Observable.combineLatest(
[
frontImageBase64.map {[weak self] in
self?.isForeigner ?? true ? $0 != nil : true
},
Observable.combineLatest(
idType.selectedItem.map {$0 != nil},
anotherIDImageBase64.map {$0 != nil}
).map { $0 ? $1 : true}
]
).map { $0.allSatisfy { $0 } }
.distinctUntilChanged()
let editingPersonalInfo = Observable.combineLatest(
emailAddress.rx.controlEvent(.editingChanged),
address.rx.controlEvent(.editingChanged),
employerName.rx.controlEvent(.editingChanged),
sourceOfFund.rx.controlEvent(.editingChanged),
monthlyIncome.rx.controlEvent(.editingChanged),
businessType.rx.controlEvent(.editingChanged),
idType.rx.controlEvent(.editingChanged),
additionalIdType.rx.controlEvent(.editingChanged)
).mapToVoid().asDriverOnErrorJustComplete()
let editingPictureInfo = Observable.combineLatest(
faceImageBase64,
anotherIDImageBase64,
frontImageBase64,
backIDImageBase64
).mapToVoid().asDriverOnErrorJustComplete()
let input = ExistingUserKycPresenter.Input(
viewWillAppear: viewWillAppear,
sendLocation: sendLocation.asDriverOnErrorJustComplete(),
employerName: employerName.rx.text.orEmpty.asDriverOnErrorJustComplete(),
sourceOfFund: sourceOfFund.selectedItem.map {$0 as? KeyValue}.asDriverOnErrorJustComplete(),
monthlyIncome: monthlyIncome.selectedItem.map {$0 as? KeyValue}.asDriverOnErrorJustComplete(),
businessType: businessType.selectedItem.map {$0 as? KeyValue}.asDriverOnErrorJustComplete(),
idType: idType.selectedItem.map {$0 as? KeyValue}.asDriverOnErrorJustComplete(),
additionalIdType: additionalIdType.selectedItem.map {$0 as? KeyValue}.asDriverOnErrorJustComplete(),
mobile: mobileNumber.rx.text.orEmpty.asDriverOnErrorJustComplete(),
email: emailAddress.rx.text.orEmpty.asDriverOnErrorJustComplete(),
address: address.rx.text.orEmpty.asDriverOnErrorJustComplete(),
isValidPersonalInfo: isValidPersonalInfo.asDriverOnErrorJustComplete(),
personalInfoSave: personalInfoSaveBttn.rx.tap.asDriverOnErrorJustComplete(),
editingPersonalInfo: editingPersonalInfo,
frontIDImage: frontImageBase64.asDriverOnErrorJustComplete(),
backIDImage: backIDImageBase64.asDriverOnErrorJustComplete(),
sideIDImage: sideIDImageBase64.asDriverOnErrorJustComplete(),
additionalIDImage: anotherIDImageBase64.asDriverOnErrorJustComplete(),
facePicture: faceImageBase64.asDriverOnErrorJustComplete(),
isValidPictures: isValidPictures.asDriverOnErrorJustComplete(),
editingPictureInfo: editingPictureInfo,
submit: pictureSaveBttn.rx.tap.asDriverOnErrorJustComplete()
)
let output = presenter.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.gpsAddress.drive(onNext: {[weak self] in
self?.address.text = $0
self?.address.sendActions(for: .editingChanged)
}).disposed(by: disposeBag)
output.idTypes.drive(onNext: {[weak self] in
let configure = TablePresenterConfiguration(presenterTitle: "select_id_type_text".localized())
self?.idType.useAsDropDown(with: configure, items: $0)
}).disposed(by: disposeBag)
output.additionaIDType.drive(onNext: {[weak self] in
let configure = TablePresenterConfiguration(presenterTitle: "select_id_type_text".localized())
self?.additionalIdType.useAsDropDown(with: configure, items: $0)
}).disposed(by: disposeBag)
output.sourceOfFund.drive(onNext: {[weak self] in
let configure = TablePresenterConfiguration(presenterTitle: "select_id_type_text".localized())
self?.sourceOfFund.useAsDropDown(with: configure, items: $0)
}).disposed(by: disposeBag)
output.monthlyIncome.drive(onNext: {[weak self] in
let configure = TablePresenterConfiguration(presenterTitle: "select_id_type_text".localized())
self?.monthlyIncome.useAsDropDown(with: configure, items: $0)
}).disposed(by: disposeBag)
output.busniessType.drive(onNext: {[weak self] in
let configure = TablePresenterConfiguration(presenterTitle: "select_id_type_text".localized())
self?.businessType.useAsDropDown(with: configure, items: $0)
}).disposed(by: disposeBag)
output.model.drive(onNext: {[weak self] model in
guard let personalInformation = model.personalInformation else { return }
self?.emailAddress.text = personalInformation.email
self?.emailAddress.sendActions(for: .editingChanged)
self?.address.text = personalInformation.address
self?.address.sendActions(for: .editingChanged)
self?.mobileNumber.text = personalInformation.mobile
self?.mobileNumber.sendActions(for: .editingChanged)
self?.employerName.text = personalInformation.occupation
self?.employerName.sendActions(for: .editingChanged)
self?.sourceOfFund.didSelect(
item: model.sourceOfFund?.first {$0.id == personalInformation.sourceOfFund}
)
self?.monthlyIncome.didSelect(
item: model.monthlyIncome?.first {$0.id == personalInformation.monthlyIncome}
)
self?.businessType.didSelect(
item: model.businessType?.first {$0.id == personalInformation.businessType}
)
self?.additionalIdType.didSelect(
item: model.additionalIdType?.first {$0.id == personalInformation.additionalIdType}
)
self?.idType.didSelect(
item: model.idType?.first {$0.id == personalInformation.idType}
)
}).disposed(by: disposeBag)
output.isSetPersonalInfoModel
.distinctUntilChanged()
.drive(onNext: {[weak self] isHidden in
self?.personalInfoSaveBttn.isHidden = isHidden
}).disposed(by: disposeBag)
output.storePersonalSuccess
.distinctUntilChanged()
.drive(onNext: {[weak self] isHidden in
guard let self = self else {return}
if self.isFirst {
self.isFirst = false
self.delegate?.newRegister(self, currentStep: .first, nextStep: .upload)
}
// self.delegate?.newRegister(self, currentStep: .first, nextStep: .upload)
}).disposed(by: disposeBag)
output.storedSuccess
.drive(onNext: {[weak self] in
guard let `self` = self else {return}
self.alert(type: .success, message: $0) {
self.delegate?.newRegister(self, currentStep: .upload, nextStep: .finish)
}
}).disposed(by: disposeBag)
isValidPersonalInfo
.distinctUntilChanged()
.asDriverOnErrorJustComplete().drive(onNext: {[weak self] isEnable in
DispatchQueue.main.async {
self?.personalInfoSaveBttn.isEnabled = isEnable
self?.personalInfoSaveBttn.backgroundColor = isEnable ? .themeRed : .lightGray
}
}).disposed(by: disposeBag)
isValidPictures
.distinctUntilChanged()
.asDriverOnErrorJustComplete().drive(onNext: {[weak self] isEnable in
DispatchQueue.main.async {
self?.pictureSaveBttn.isEnabled = isEnable
self?.pictureSaveBttn.backgroundColor = isEnable ? .themeRed : .lightGray
}
}).disposed(by: disposeBag)
}
private func setMultiLanguages() {
}
}
extension ExistingUserKycViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
hideProgressHud()
guard let location = manager.location else { return }
sendLocation.onNext(location)
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
hideProgressHud()
locationManager.stopUpdatingLocation()
let alert = UIAlertController(
title: "settings_text".localized(),
message: "Allow location from settings",
preferredStyle: .alert
)
self.present(alert, animated: true, completion: nil)
alert.addAction(UIAlertAction(title: "Move setting", style: .default, handler: { action in
switch action.style {
case .default:
UIApplication
.shared
.open(
NSURL(string: UIApplication.openSettingsURLString)! as URL,
options: [:],
completionHandler: nil
)
case .cancel: print("cancel")
case .destructive: print("destructive")
@unknown default: break
}
}))
}
}
// MARK: MultimediaPresenterProtocol
extension ExistingUserKycViewController: MultimediaPresenterProtocol {
func presenting() -> UIViewController {
return self
}
}
// MARK: MultiMediaManagerDelegate
extension ExistingUserKycViewController: MultiMediaManagerDelegate {
func didFinishPickingWithImage(image: UIImage) {
self.imageCropper?.cropImage(image: image)
}
func didFinishPickingWithError(error: String) {
self.alert(type: .error, message: error)
}
func hideBorder(view: UIView?) {
view?.layer.borderWidth = 0
view?.layer.addShadow(with: .clear)
}
}
// MARK: ImageCropperDelegate
extension ExistingUserKycViewController: ImageCropperDelegate {
func didCropWith(image: UIImage) {
switch photoType {
case .frontID:
frontIDImageTrigger.onNext(image.toBase64())
case .backID:
backIDImageTrigger.onNext(image.toBase64())
case .sideID:
sideIDImageTrigger.onNext(image.toBase64())
case .facePicture:
faceImageTrigger.onNext(image.toBase64())
case .anotherID:
anotherIDImageTrigger.onNext(image.toBase64())
}
}
func didFailedCropWith(error: Error) {
self.alert(type: .error, message: error.localizedDescription)
}
}

44
GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/User Interface/Wireframe/ExistingUserKycWireframe.swift

@ -0,0 +1,44 @@
//
// ExistingUserKycWireframe.swift
// GME Remit
//
// Created by Shiran on 8/18/20.
//Copyright © 2020 Gobal Money Express Co. Ltd. All rights reserved.
//
import UIKit
class ExistingUserKycWireframe {
weak var view: UIViewController!
weak var delegate: NewRegisterDelegate?
var step: NewRegisterViewController.Step = .first
}
extension ExistingUserKycWireframe: ExistingUserKycWireframeInput {
var storyboardName: String {return "ExistingUserKyc"}
func getMainView() -> UIViewController {
let service = ExistingUserKycService()
let interactor = ExistingUserKycInteractor(service: service)
let presenter = ExistingUserKycPresenter()
let viewController = viewControllerFromStoryboard(of: ExistingUserKycViewController.self)
viewController.presenter = presenter
viewController.delegate = delegate
viewController.view.tag = 0
viewController.step = self.step
interactor.output = presenter
presenter.interactor = interactor
presenter.wireframe = self
self.view = viewController
return viewController
}
func getMainView(with delegate: NewRegisterDelegate?, step: NewRegisterViewController.Step = .first) -> UIViewController {
self.delegate = delegate
self.step = step
return getMainView()
}
}

13
GME Remit/Modules/RegisterModules/UserAuthentication/ExistingUserKyc/User Interface/Wireframe/ExistingUserKycWireframeInput.swift

@ -0,0 +1,13 @@
//
// ExistingUserKycWireframeInput.swift
// GME Remit
//
// Created by Shiran on 8/18/20.
//Copyright © 2020 Gobal Money Express Co. Ltd. All rights reserved.
//
import Foundation
protocol ExistingUserKycWireframeInput: WireframeInput {
}

6
GME Remit/Modules/RegisterModules/UserAuthentication/KYCVerifyStep1/Application Logic/Service/KYCVerifyStep1Service.swift

@ -14,7 +14,11 @@ class KYCVerifyStep1Service: KYCVerifyStep1ServiceType {
success: @escaping (KYCInfoModel) -> Void,
failure: @escaping (Error) -> Void
) {
APIRouter.loadKYCInformation.json(needsAuthorization: false, success: success, failure: failure)
APIRouter.loadKYCInformation.json(
needsAuthorization: false,
success: success,
failure: failure
)
}
func saveKycInfo(

9
GME Remit/Modules/RegisterModules/UserAuthentication/KYCVerifyStep1/User Interface/View/KYCVerifyStep1ViewController.swift

@ -563,15 +563,6 @@ extension KYCVerifyStep1ViewController {
output.model.drive(onNext: {[weak self] model in
guard let personalInformation = model.personalInformation else { return }
//
// let isForeigner = (personalInformation.nativeCountry ?? "").lowercased() == "kr" ? false : true
//
// if isForeigner {
// self?.idTypeTextField.validCondition = nil
// } else {
// self?.idTypeTextField.validCondition = {!$0.isEmpty}
// }
// self?.isForeigner = isForeigner
self?.emailTextField.text = personalInformation.email
self?.emailTextField.sendActions(for: .editingChanged)

16
GME Remit/Modules/RegisterModules/UserAuthentication/NewRegister/User Interface/Wireframe/NewRegisterWireframe.swift

@ -13,6 +13,7 @@ import LGSideMenuController
class NewRegisterWireframe {
weak var view: UIViewController!
var selectedWireframe = ""
private var stepper: BehaviorSubject<NewRegisterViewController.Step>?
private var step1VC: UIViewController!
@ -26,8 +27,17 @@ extension NewRegisterWireframe: NewRegisterWireframeInput {
var storyboardName: String {return "NewRegister"}
func getMainView() -> UIViewController {
if selectedWireframe == "ExistingUser" {
print("selectedWireframe is::\(selectedWireframe)")
print("existingUser")
step1VC = ExistingUserKycWireframe().getMainView(with: self, step: .first)
step2VC = ExistingUserKycWireframe().getMainView(with: self, step: .upload)
}else {
print("in kyc verify")
print("selectedWireframe is::\(selectedWireframe)")
step1VC = KYCVerifyStep1Wireframe().getMainView(with: self, step: .first)
step2VC = KYCVerifyStep1Wireframe().getMainView(with: self, step: .upload)
}
let service = NewRegisterService()
let interactor = NewRegisterInteractor(service: service)
@ -189,6 +199,12 @@ extension NewRegisterWireframe: NewRegisterWireframeInput {
}
)
}
func selectedView(in source: UINavigationController, viewName: String) {
selectedWireframe = viewName
let mainView = self.getMainView()
source.pushViewController(mainView, animated: true)
}
}
extension NewRegisterWireframe: NewRegisterDelegate {

Loading…
Cancel
Save