Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Changelog
=========
[1.0.1](https://github.com/hyperwallet/hyperwallet-ios-ui-sdk/releases/tag/1.0.0-beta21)
-------------------
- Automatically select the default currency code based on the country's configuration

[1.0.0-beta21](https://github.com/hyperwallet/hyperwallet-ios-ui-sdk/releases/tag/1.0.0-beta21)
-------------------
- Update privacy manifest
Expand Down
2 changes: 1 addition & 1 deletion Cartfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
github "hyperwallet/hyperwallet-ios-sdk" "1.0.0-beta20"
github "hyperwallet/hyperwallet-ios-sdk" "1.0.1"
github "hyperwallet/hyperwallet-ios-insight" "1.0.0-beta08"
2 changes: 1 addition & 1 deletion Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
github "JanGorman/Hippolyte" "1.4.1"
github "httpswift/swifter" "1.5.0"
github "hyperwallet/hyperwallet-ios-insight" "1.0.0-beta08"
github "hyperwallet/hyperwallet-ios-sdk" "1.0.0-beta20"
github "hyperwallet/hyperwallet-ios-sdk" "1.0.1"
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,21 @@ Adding one or more of these frameworks allows users to explore the particular fu
### Carthage
Specify it in your Cartfile:
```ogdl
github "hyperwallet/hyperwallet-ios-ui-sdk" "1.0.0-beta21"
github "hyperwallet/hyperwallet-ios-ui-sdk" "1.0.1"
```
Add desired modules using the `Linked Frameworks and Libraries` option to make them available in the app.
Use `import <module-name>` to add the dependency within a file

### CocoaPods
- Install a specific framework (install one or more frameworks based on your requirement)
```ruby
pod "HyperwalletUISDK/TransferMethod", "1.0.0-beta21"
pod "HyperwalletUISDK/Transfer", "1.0.0-beta21"
pod "HyperwalletUISDK/Receipt", "1.0.0-beta21"
pod "HyperwalletUISDK/TransferMethod", "1.0.1"
pod "HyperwalletUISDK/Transfer", "1.0.1"
pod "HyperwalletUISDK/Receipt", "1.0.1"
```
- To install all available modules (TransferMethod, Transfer, Receipt)
```ruby
pod 'HyperwalletUISDK', '~> 1.0.0-beta21'
pod 'HyperwalletUISDK', '~> 1.0.1'
```
Use `import HyperwalletUISDK` to add the dependency within a file.

Expand Down
123 changes: 71 additions & 52 deletions TransferMethod/Sources/SelectTransferMethodTypePresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,31 +64,31 @@ final class SelectTransferMethodTypePresenter {
private let linkTransferMethod = "select-transfer-method"
private var selectedTransferMethodType = ""
private var hyperwalletInsights: HyperwalletInsightsProtocol

private lazy var transferMethodConfigurationRepository = {
TransferMethodRepositoryFactory.shared.transferMethodConfigurationRepository()
}()

private lazy var userRepository: UserRepository = {
UserRepositoryFactory.shared.userRepository()
}()

private(set) var sectionData = [HyperwalletTransferMethodType]()

/// Initialize SelectTransferMethodPresenter
init(_ view: SelectTransferMethodTypeView,
_ hyperwalletInsights: HyperwalletInsightsProtocol = HyperwalletInsights.shared) {
self.view = view
self.hyperwalletInsights = hyperwalletInsights
}

/// Return the countryCurrency item composed by the tuple (title and value)
func getCountryCurrencyConfiguration(indexPath: IndexPath) -> CountryCurrencyCellConfiguration {
let title = countryCurrencySectionData[indexPath.row]
return CountryCurrencyCellConfiguration(title: title.localized(),
value: countryCurrencyValues(at: indexPath.row))
}

/// Display all the select Country or Currency based on the index
func performShowSelectCountryOrCurrencyView(index: Int) {
transferMethodConfigurationRepository.getKeys(completion: self.getKeysHandler(
Expand All @@ -100,18 +100,18 @@ final class SelectTransferMethodTypePresenter {
}
}))
}

/// Loads the transferMethodKeys from core SDK and display the default transfer methods
///
/// - Parameter forceUpdate: Forces to refresh the data
func loadTransferMethodKeys(_ forceUpdate: Bool = false) {
view?.showLoading()

if forceUpdate {
userRepository.refreshUser()
transferMethodConfigurationRepository.refreshKeys()
}

userRepository.getUser { [weak self] getUserResult in
guard let strongSelf = self, let view = strongSelf.view else {
return
Expand All @@ -124,7 +124,7 @@ final class SelectTransferMethodTypePresenter {
pageGroup: strongSelf.pageGroup) {
strongSelf.loadTransferMethodKeys()
}

case .success(let user):
strongSelf.transferMethodConfigurationRepository
.getKeys(completion: strongSelf.getKeysHandler(
Expand All @@ -148,11 +148,11 @@ final class SelectTransferMethodTypePresenter {
view.hideLoading()
strongSelf.loadTransferMethodKeys()
})
)
)
}
}
}

/// Navigate to AddTransferMethodController
func navigateToAddTransferMethod(_ index: Int) {
if let transferMethodTypeCode = self.sectionData[index].code {
Expand All @@ -163,45 +163,45 @@ final class SelectTransferMethodTypePresenter {
guard let strongSelf = self else {
return
}

if case let .success(user) = getUserResult,
let profileType = user?.profileType?.rawValue {
let profileType = user?.profileType?.rawValue {
strongSelf.view?
.navigateToAddTransferMethodController(
country: strongSelf.selectedCountry,
currency: strongSelf.selectedCurrency,
profileType: profileType,
transferMethodTypeCode: strongSelf.selectedTransferMethodType
)
)
}
}
}

private func countryCurrencyValues(at index: Int) -> String {
return (index == 0
? Locale.current.localizedString(forRegionCode: selectedCountry) ?? selectedCountry
: selectedCurrency)
? Locale.current.localizedString(forRegionCode: selectedCountry) ?? selectedCountry
: selectedCurrency)
}

private func getKeysHandler(
success: @escaping ((HyperwalletTransferMethodConfigurationKey?) -> Void),
failure: (() -> Void)? = nil)
-> (Result<HyperwalletTransferMethodConfigurationKey?, HyperwalletErrorType>) -> Void {
-> (Result<HyperwalletTransferMethodConfigurationKey?, HyperwalletErrorType>) -> Void {
return { [weak self] (result) in
guard let strongSelf = self, let view = strongSelf.view else {
return
}

switch result {
case .failure(let error):
view.showError(error, pageName: strongSelf.pageName, pageGroup: strongSelf.pageGroup, failure)

case .success(let keyResult):
success(keyResult)
}
}
}

/// Shows the Select Country View
private func showSelectCountryView(_ countries: [GenericCellConfiguration]?) {
if let countries = countries {
Expand All @@ -212,7 +212,7 @@ final class SelectTransferMethodTypePresenter {
filterContentHandler: filterContentHandler())
}
}

/// Shows the Select Currency View
private func showSelectCurrencyView(_ currencies: [GenericCellConfiguration]?) {
if let currencies = currencies {
Expand All @@ -223,7 +223,7 @@ final class SelectTransferMethodTypePresenter {
filterContentHandler: filterContentHandler())
}
}

private func selectCountryHandler() -> SelectTransferMethodTypeView.SelectItemHandler {
return { (country) in
if let country = country.value {
Expand All @@ -240,7 +240,7 @@ final class SelectTransferMethodTypePresenter {
}))
}
}

private func selectCurrencyHandler() -> SelectTransferMethodTypeView.SelectItemHandler {
return { [weak self](currency) in
guard let strongSelf = self
Expand All @@ -259,47 +259,47 @@ final class SelectTransferMethodTypePresenter {

private func retrieveTransferMethodTypesFeesAndProcessingTimes(
completion: @escaping ([HyperwalletTransferMethodType]?) -> Void) {
transferMethodConfigurationRepository
.getTransferMethodTypesFeesAndProcessingTimes(country: selectedCountry,
currency: selectedCurrency) { [weak self] (result) in
guard let strongSelf = self, let view = strongSelf.view else {
return
}
view.hideLoading()
switch result {
case .failure(let error):
view.showError(error, pageName: strongSelf.pageName, pageGroup: strongSelf.pageGroup) {
strongSelf.loadTransferMethodKeys()
transferMethodConfigurationRepository
.getTransferMethodTypesFeesAndProcessingTimes(country: selectedCountry,
currency: selectedCurrency) { [weak self] (result) in
guard let strongSelf = self, let view = strongSelf.view else {
return
}
view.hideLoading()
switch result {
case .failure(let error):
view.showError(error, pageName: strongSelf.pageName, pageGroup: strongSelf.pageGroup) {
strongSelf.loadTransferMethodKeys()
}

case .success(let keyResult):
completion(keyResult?.transferMethodTypes(countryCode: strongSelf.selectedCountry,
currencyCode: strongSelf.selectedCurrency))
}

case .success(let keyResult):
completion(keyResult?.transferMethodTypes(countryCode: strongSelf.selectedCountry,
currencyCode: strongSelf.selectedCurrency))
}
}
}

}

private func filterContentHandler() -> SelectTransferMethodTypeView.FilterContentHandler {
return {(items, searchText) in
items.filter {
$0.title?.lowercased().contains(searchText.lowercased()) ?? false ||
$0.value?.lowercased().contains(searchText.lowercased()) ?? false
$0.value?.lowercased().contains(searchText.lowercased()) ?? false
}
}
}

private func countryMarkCellHandler() -> SelectTransferMethodTypeView.MarkCellHandler {
return { [weak self] item in
self?.selectedCountry == item.value
}
}

private func currencyMarkCellHandler() -> SelectTransferMethodTypeView.MarkCellHandler {
return { [weak self] item in
self?.selectedCurrency == item.value
}
}

private func loadSelectedCountry(_ countries: [HyperwalletCountry],
with userCountry: String?) {
if let userCountry = userCountry, countries.contains(where: { $0.value == userCountry }) {
Expand All @@ -308,17 +308,36 @@ final class SelectTransferMethodTypePresenter {
selectedCountry = countryValue
}
}

private func loadCurrency(_ keys: HyperwalletTransferMethodConfigurationKey?) {
guard let firstCurrency = keys?.currencies(from: selectedCountry)?.first,
let currencyCode = firstCurrency.code else {
view?.showAlert(message: String(format: "no_currency_available_error_message".localized(), selectedCountry))
guard let countries = keys?.countries(),
let country = countries.first(where: { $0.code == selectedCountry }),
let currencyCode = getCurrencyCode(country, keys) else {
// Handle the case when country is not found
view?.showAlert(message:
String(format: "no_currency_available_error_message".localized(), selectedCountry))
return
}

// Define selected currency
selectedCurrency = currencyCode

// Reload the view with the updated currency data
view?.reloadCountryCurrencyData()
}

private func getCurrencyCode(_ country: HyperwalletCountry,
_ keys: HyperwalletTransferMethodConfigurationKey?) -> String? {
if let defaultCurrencyCode = country.defaultCurrencyCode,
let defaultCurrency = keys?.currencies(from: selectedCountry)?
.first(where: { $0.code == defaultCurrencyCode }) {
// retun the country's default currency, if it present on the currency list
return defaultCurrency.code
}

return keys?.currencies(from: selectedCountry)?.first?.code
}

private func loadTransferMethodTypesFeesAndProcessingTimes(
_ transferMethodTypes: [HyperwalletTransferMethodType]?) {
guard let transferMethodTypes = transferMethodTypes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@
{
"code": "US",
"name": "UNITED STATES",
"defaultCurrencyCode": "USD",
"currencies": {
"nodes": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,13 @@ class SelectTransferMethodTypePresenterTests: XCTestCase {

// Then
XCTAssertEqual(presenter.selectedCountry, "US", "The country should be US")
XCTAssertEqual(presenter.selectedCurrency, "CAD", "The currency should be CAD")
XCTAssertEqual(presenter.selectedCurrency, "USD", "The currency should be CAD")
XCTAssertTrue(mockView.isNavigateToAddTransferMethodControllerPerformed,
"The navigateToAddTransferMethodControllerPerformed should be performed")

XCTAssertEqual(mockView.profileType, "INDIVIDUAL", "The profileType should be INDIVIDUAL")
XCTAssertEqual(presenter.countryCurrencySectionData.count, 2, "The countryCurrencyCount should be 2")
XCTAssertEqual(presenter.sectionData.count, 1, "The transferMethodTypesCount should be 1")
XCTAssertEqual(presenter.sectionData.count, 3, "The transferMethodTypesCount should be 3")
XCTAssertTrue(hyperwalletInsightsMock.didTrackClick, "HyperwalletInsights.trackClick should be called")
XCTAssertNotNil(presenter.getCountryCurrencyConfiguration(indexPath: indexPath),
"The country currency cell configuration should not be nil")
Expand Down