Skip to content

Commit

Permalink
Merge branch 'develop' into COIOS-774_pay-by-bank-improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
goergisn authored Oct 29, 2024
2 parents dc5436c + c22eb45 commit ff32640
Show file tree
Hide file tree
Showing 30 changed files with 535 additions and 57 deletions.
4 changes: 2 additions & 2 deletions Adyen.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ Pod::Spec.new do |s|
s.subspec 'CashAppPay' do |plugin|
plugin.source_files = 'AdyenCashAppPay/**/*.swift'
plugin.dependency 'Adyen/Core'
plugin.dependency 'CashAppPayKit', '0.5.1'
plugin.dependency 'CashAppPayKitUI', '0.5.1'
plugin.dependency 'CashAppPayKit', '0.6.2'
plugin.dependency 'CashAppPayKitUI', '0.6.2'
end

s.subspec 'AdyenTwint' do |plugin|
Expand Down
10 changes: 9 additions & 1 deletion Adyen.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@
81272F182CC7E1DD00D8773A /* PayByBankUSComponent+ConfirmationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81272F172CC7E1CF00D8773A /* PayByBankUSComponent+ConfirmationViewController.swift */; };
81272F1A2CC8FD4600D8773A /* PayByBankUSComponent+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81272F192CC8FD4600D8773A /* PayByBankUSComponent+Style.swift */; };
8128977C2CCA660A00275487 /* StoredPayByBankUSPaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 812897752CC8FEC100275487 /* StoredPayByBankUSPaymentMethod.swift */; };
8128977B2CC93CB100275487 /* SupportedPaymentMethodsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8128977A2CC93CB000275487 /* SupportedPaymentMethodsView.swift */; };
8128977E2CCA6FE900275487 /* SupportedPaymentMethodLogosViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8128977D2CCA6FE400275487 /* SupportedPaymentMethodLogosViewTests.swift */; };
8136619E2BE0F6F7009AA0CD /* Adyen3DS2 in Frameworks */ = {isa = PBXBuildFile; productRef = 8136619D2BE0F6F7009AA0CD /* Adyen3DS2 */; };
813BF1122B2365400096940E /* XCTestCase+FirstResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 813BF1102B2364E00096940E /* XCTestCase+FirstResponder.swift */; };
813BF1132B2365400096940E /* XCTestCase+FirstResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 813BF1102B2364E00096940E /* XCTestCase+FirstResponder.swift */; };
Expand Down Expand Up @@ -1613,6 +1615,8 @@
81272F172CC7E1CF00D8773A /* PayByBankUSComponent+ConfirmationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PayByBankUSComponent+ConfirmationViewController.swift"; sourceTree = "<group>"; };
81272F192CC8FD4600D8773A /* PayByBankUSComponent+Style.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PayByBankUSComponent+Style.swift"; sourceTree = "<group>"; };
812897752CC8FEC100275487 /* StoredPayByBankUSPaymentMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoredPayByBankUSPaymentMethod.swift; sourceTree = "<group>"; };
8128977A2CC93CB000275487 /* SupportedPaymentMethodsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportedPaymentMethodsView.swift; sourceTree = "<group>"; };
8128977D2CCA6FE400275487 /* SupportedPaymentMethodLogosViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportedPaymentMethodLogosViewTests.swift; sourceTree = "<group>"; };
813BF1102B2364E00096940E /* XCTestCase+FirstResponder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCTestCase+FirstResponder.swift"; sourceTree = "<group>"; };
813EF9DD2A5DA0BC00C65D15 /* FormPickerItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormPickerItem.swift; sourceTree = "<group>"; };
813EF9E12A5DA2D400C65D15 /* FormPickerItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormPickerItemView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3029,6 +3033,7 @@
children = (
F9FE39E22679E09200F02A9B /* LoadingViewTests.swift */,
81A2E3BD2A5C453200CF5F9C /* LinkTextViewTests.swift */,
8128977D2CCA6FE400275487 /* SupportedPaymentMethodLogosViewTests.swift */,
);
path = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -4003,6 +4008,7 @@
81B001C12A55C5C10015BFA3 /* UISearchBar+Prominent.swift */,
81BBB6732A82792100C1A04B /* UIView+Accessibility.swift */,
E2C0E0C0220D7E5E008616F6 /* SubmitButton.swift */,
8128977A2CC93CB000275487 /* SupportedPaymentMethodsView.swift */,
81A2E3BF2A5C453F00CF5F9C /* LinkTextView.swift */,
F95A788725C416A60032CF7E /* CopyLabelView.swift */,
F99D2F852665211600BB5B2F /* LoadingView.swift */,
Expand Down Expand Up @@ -6797,6 +6803,7 @@
E216D3C5221AEF450013CBCF /* IBANFormatter.swift in Sources */,
5A4702182664E9440023F264 /* APIContext.swift in Sources */,
E9AFF87A224A4C9C005A0D8D /* PaymentComponent.swift in Sources */,
8128977B2CC93CB100275487 /* SupportedPaymentMethodsView.swift in Sources */,
006DCC03295C3E930015EA79 /* SegmentedControlStyle.swift in Sources */,
E216D3C0221AD0620013CBCF /* FormViewItemManager.swift in Sources */,
00EACBB3287327C00082B360 /* FormIssuerPickerItem.swift in Sources */,
Expand Down Expand Up @@ -7263,6 +7270,7 @@
E7085C1E2629FDD700D0153B /* RedirectListnerTests.swift in Sources */,
E74CE3DF26727EB1008231D2 /* DropInDelegateMock.swift in Sources */,
A020EC5A29ED33F90050B2FE /* CashAppPayComponentTests.swift in Sources */,
8128977E2CCA6FE900275487 /* SupportedPaymentMethodLogosViewTests.swift in Sources */,
F967581527D25B1600A16FB6 /* SelfRetainingAPIClientTests.swift in Sources */,
81088A252BDBC2DD007FCDB9 /* CancellableMock.swift in Sources */,
81DA70892BDA6075006CE5D5 /* TwintSDKActionTests+Convenience.swift in Sources */,
Expand Down Expand Up @@ -9493,7 +9501,7 @@
repositoryURL = "https://github.com/cashapp/cash-app-pay-ios-sdk";
requirement = {
kind = exactVersion;
version = 0.5.1;
version = 0.6.2;
};
};
E72375CC27AAB7760020DCF9 /* XCRemoteSwiftPackageReference "adyen-wechatpay-ios" */ = {
Expand Down
2 changes: 1 addition & 1 deletion Adyen/Core/Core Protocols/PaymentMethod.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public extension PaymentMethod {
title: merchantProvidedDisplayInformation.title,
subtitle: subtitle,
logoName: defaultDisplayInformation.logoName,
disclosureText: defaultDisplayInformation.disclosureText,
trailingInfo: defaultDisplayInformation.trailingInfo,
footnoteText: defaultDisplayInformation.footnoteText
)
}
Expand Down
40 changes: 36 additions & 4 deletions Adyen/Core/Models/DisplayInformation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ import Foundation
/// Describes a payment method display information.
public struct DisplayInformation: Equatable {

@_spi(AdyenInternal)
public enum TrailingInfoType: Equatable {
case text(String)
case logos(named: [String], trailingText: String?)

internal var accessibilityLabel: String? {
switch self {
case let .text(text): return text
case .logos: return nil
}
}
}

/// The title for the payment method, adapted for displaying in a list.
/// In the case of stored payment methods, this will include information identifying the stored payment method.
/// For example, this could be the last 4 digits of the card number, or the used email address.
Expand All @@ -23,9 +36,9 @@ public struct DisplayInformation: Equatable {
@_spi(AdyenInternal)
public let logoName: String

/// The trailing disclosure text.
/// The trailing info element
@_spi(AdyenInternal)
public let disclosureText: String?
public let trailingInfo: TrailingInfoType?

/// The footnote if any.
@_spi(AdyenInternal)
Expand All @@ -37,7 +50,7 @@ public struct DisplayInformation: Equatable {

// TODO: Allow adding a custom view - to show the bank icons

/// Initializes a`DisplayInformation`.
/// Initializes a `DisplayInformation`
///
/// - Parameter title: The title.
/// - Parameter subtitle: The subtitle.
Expand All @@ -53,11 +66,30 @@ public struct DisplayInformation: Equatable {
disclosureText: String? = nil,
footnoteText: String? = nil,
accessibilityLabel: String? = nil
) {
self.init(
title: title,
subtitle: subtitle,
logoName: logoName,
trailingInfo: disclosureText.map { .text($0) },
footnoteText: footnoteText,
accessibilityLabel: accessibilityLabel
)
}

@_spi(AdyenInternal)
public init(
title: String,
subtitle: String?,
logoName: String,
trailingInfo: TrailingInfoType?,
footnoteText: String? = nil,
accessibilityLabel: String? = nil
) {
self.title = title
self.subtitle = subtitle
self.logoName = logoName
self.disclosureText = disclosureText
self.trailingInfo = trailingInfo
self.footnoteText = footnoteText
self.accessibilityLabel = accessibilityLabel
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ private struct PaymentMethodField: Decodable {
}
}

// swiftlint:disable file_length
internal enum AnyPaymentMethodDecoder {

private static var decoders: [PaymentMethodType: PaymentMethodDecoder] = [
Expand Down Expand Up @@ -535,3 +536,5 @@ private struct TwintPaymentMethodDecoder: PaymentMethodDecoder {
return nil
}
}

// swiftlint:enable file_length
1 change: 1 addition & 0 deletions Adyen/Helpers/UIImageViewHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ public extension AdyenScope where Base: UIImageView {
base.layer.borderWidth = style.borderWidth
base.backgroundColor = style.backgroundColor
base.tintColor = style.tintColor
base.clipsToBounds = style.clipsToBounds
}
}
1 change: 1 addition & 0 deletions Adyen/Model/PrefilledShopperInformation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public struct PrefilledShopperInformation: ShopperInformation {
/// - deliveryAddress: The delivery address of the shopper, optional.
/// - socialSecurityNumber: The social security number of the shopper, optional.
/// - card: Shopper's card basic information, optional.
// swiftlint:disable:next line_length
@available(*, deprecated, renamed: "init(shopperName:emailAddress:phoneNumber:billingAddress:deliveryAddress:socialSecurityNumber:card:)")
public init(
shopperName: ShopperName? = nil,
Expand Down
4 changes: 2 additions & 2 deletions Adyen/UI/Form/Items/Text/FormTextItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ open class FormTextItem: FormValidatableValueItem<String>, InputViewRequiringFor
textDidChange(value: value)
}

@_spi(AdyenInternal)
@discardableResult
internal func textDidChange(value: String) -> String {
public func textDidChange(value: String) -> String {
let sanitizedValue = formatter?.sanitizedValue(for: value) ?? value

publisher.wrappedValue = sanitizedValue
formattedValue = formatter?.formattedValue(for: value) ?? value
return formattedValue
}

}

@_spi(AdyenInternal)
Expand Down
11 changes: 9 additions & 2 deletions Adyen/UI/Form/Items/Text/FormTextItemView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,18 @@ open class FormTextItemView<ItemType: FormTextItem>: FormValidatableValueItemVie

// MARK: - Private

@objc private func textDidChange(textField: UITextField) {
@_spi(AdyenInternal)
@objc open func textDidChange(textField: UITextField) {
textField.text = item.textDidChange(value: textField.text ?? "")
notifyDelegateOfMaxLengthIfNeeded()
}

@_spi(AdyenInternal)
open func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// Making it available for subclassing
true
}

// MARK: - Validation

override public var isValid: Bool {
Expand Down Expand Up @@ -265,7 +272,7 @@ open class FormTextItemView<ItemType: FormTextItem>: FormValidatableValueItemVie

public func notifyDelegateOfMaxLengthIfNeeded() {
let maximumLength = item.validator?.maximumLength(for: item.value) ?? .max
if item.value.count == maximumLength {
if item.value.count >= maximumLength {
delegate?.didReachMaximumLength(in: self)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private extension FormPickable {
title: title,
subtitle: subtitle,
icon: listItemIcon,
trailingText: trailingText,
trailingInfo: trailingText.map { .text($0) },
identifier: identifier,
selectionHandler: { selectionHandler(self) }
)
Expand Down
24 changes: 20 additions & 4 deletions Adyen/UI/List/ListItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ import Foundation
@_spi(AdyenInternal)
public class ListItem: FormItem {

public enum TrailingInfoType {
case text(String)
case logos(urls: [URL], trailingText: String?)

internal var accessibilityLabel: String? {
switch self {
case let .text(text): return text
case .logos: return nil
}
}
}

public var isHidden: AdyenObservable<Bool> = AdyenObservable(false)

public var subitems: [FormItem] = []
Expand All @@ -27,7 +39,7 @@ public class ListItem: FormItem {
public var icon: Icon?

/// The trailing text of the item.
public var trailingText: String?
public var trailingInfo: TrailingInfoType?

/// The handler to invoke when the item is selected.
public var selectionHandler: (() -> Void)?
Expand Down Expand Up @@ -61,7 +73,7 @@ public class ListItem: FormItem {
title: String,
subtitle: String? = nil,
icon: Icon? = nil,
trailingText: String? = nil,
trailingInfo: TrailingInfoType? = nil,
style: ListItemStyle = ListItemStyle(),
identifier: String? = nil,
accessibilityLabel: String? = nil,
Expand All @@ -70,10 +82,14 @@ public class ListItem: FormItem {
self.title = title
self.subtitle = subtitle
self.icon = icon
self.trailingText = trailingText
self.trailingInfo = trailingInfo
self.style = style
self.identifier = identifier
self.accessibilityLabel = accessibilityLabel ?? [title, subtitle, trailingText].compactMap { $0 }.joined(separator: ", ")
self.accessibilityLabel = accessibilityLabel ?? [
title,
subtitle,
trailingInfo?.accessibilityLabel
].compactMap { $0 }.joined(separator: ", ")
self.selectionHandler = selectionHandler
}

Expand Down
55 changes: 42 additions & 13 deletions Adyen/UI/List/ListItemView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ public final class ListItemView: UIView, AnyFormItemView {
updateImageView(style: style)
titleLabel.adyen.apply(style.title)
subtitleLabel.adyen.apply(style.subtitle)
trailingTextLabel.adyen.apply(style.trailingText)

if let trailingTextLabel = trailingView as? UILabel {
trailingTextLabel.adyen.apply(style.trailingText)
}
}
}
}
Expand All @@ -67,11 +70,7 @@ public final class ListItemView: UIView, AnyFormItemView {
ViewIdentifierBuilder.build(scopeInstance: $0, postfix: "subtitleLabel")
}

trailingTextLabel.text = item?.trailingText
trailingTextLabel.isHidden = item?.trailingText?.isEmpty ?? true
trailingTextLabel.accessibilityIdentifier = item?.identifier.map {
ViewIdentifierBuilder.build(scopeInstance: $0, postfix: "trailingTextLabel")
}
updateTrailingView(for: item)

imageView.isHidden = item?.icon == nil
updateIcon()
Expand All @@ -90,6 +89,37 @@ public final class ListItemView: UIView, AnyFormItemView {
}
}

private func updateTrailingView(for item: ListItem?) {
contentStackView.removeArrangedSubview(trailingView)
trailingView.removeFromSuperview()

switch item?.trailingInfo {
case let .text(string):
let trailingTextLabel = UILabel()
trailingTextLabel.translatesAutoresizingMaskIntoConstraints = false
trailingTextLabel.text = string
trailingTextLabel.accessibilityIdentifier = item?.identifier.map {
ViewIdentifierBuilder.build(scopeInstance: $0, postfix: "trailingTextLabel")
}
trailingView = trailingTextLabel
trailingView.isHidden = string.isEmpty
case let .logos(urls, trailingText):
let trailingLogosView = SupportedPaymentMethodLogosView(
imageUrls: urls,
trailingText: trailingText
)
trailingLogosView.accessibilityIdentifier = item?.identifier.map {
ViewIdentifierBuilder.build(scopeInstance: $0, postfix: "trailingLogosView")
}
trailingView = trailingLogosView
case nil:
trailingView = UIView()
trailingView.isHidden = true
}

contentStackView.addArrangedSubview(trailingView)
}

private func updateImageView(style: ListItemStyle) {
imageView.contentMode = style.image.contentMode

Expand Down Expand Up @@ -140,11 +170,10 @@ public final class ListItemView: UIView, AnyFormItemView {
return subtitleLabel
}()

private lazy var trailingTextLabel: UILabel = {
let trailingTextLabel = UILabel()
trailingTextLabel.translatesAutoresizingMaskIntoConstraints = false
trailingTextLabel.isHidden = true
return trailingTextLabel
private var trailingView: UIView = {
let view = UIView()
view.isHidden = true
return view
}()

// MARK: - Text Stack View
Expand All @@ -160,7 +189,7 @@ public final class ListItemView: UIView, AnyFormItemView {
}()

private lazy var contentStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [imageView, titleSubtitleStackView, trailingTextLabel])
let stackView = UIStackView(arrangedSubviews: [imageView, titleSubtitleStackView, trailingView])
stackView.setCustomSpacing(16, after: imageView)
stackView.spacing = 8
stackView.translatesAutoresizingMaskIntoConstraints = false
Expand Down Expand Up @@ -188,7 +217,7 @@ public final class ListItemView: UIView, AnyFormItemView {
self.heightAnchor.constraint(greaterThanOrEqualToConstant: 48)
]

trailingTextLabel.setContentHuggingPriority(.required, for: .horizontal)
trailingView.setContentHuggingPriority(.required, for: .horizontal)
imageView.setContentHuggingPriority(.required, for: .horizontal)

NSLayoutConstraint.activate(constraints)
Expand Down
Loading

0 comments on commit ff32640

Please sign in to comment.