Skip to content

Commit

Permalink
Merge branch 'develop' into feature_Twint
Browse files Browse the repository at this point in the history
  • Loading branch information
neelSharma12 authored Mar 5, 2024
2 parents b3e6dbf + 5796859 commit 8b48062
Show file tree
Hide file tree
Showing 76 changed files with 821 additions and 685 deletions.
20 changes: 18 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ jobs:
include:

- version: '16.4'
displayname: 'iPhone 14'
runtime: 'iOS-16-4'
device: 'iPhone 14'
displayname: 'iPhone-14'
os: 'macos-13-xl'
xcode_version: '14.3'
needs_custom_sim: false # Takes the shipped simulator that comes with Xcode 14

- version: '15.0'
Expand Down Expand Up @@ -51,10 +54,23 @@ jobs:
run: |
sudo mkdir -p /Library/Developer/CoreSimulator/Profiles/Runtimes
- name: Prepare ${{ matrix.version }}
- name: Select Xcode ${{ matrix.xcode_version }}
if: matrix.xcode_version != ''
run: |
ls /Applications/Xcode_*.app
sudo xcode-select -s /Applications/Xcode_${xcode_version}.app/Contents/Developer
env:
xcode_version: ${{ matrix.xcode_version }}

- name: Download simulator if needed (${{ matrix.version }})
if: matrix.needs_custom_sim
run: |
xcversion simulators --install="iOS ${version}"
env:
version: ${{ matrix.version }}

- name: Create simulator ${{ matrix.version }}
run: |
xcrun simctl list devices ${version}
xcrun simctl create ${displayname} "${device}" "com.apple.CoreSimulator.SimRuntime.${runtime}"
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/format_project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
brew install swiftformat
swiftformat .
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v6
with:
delete-branch: true
branch: format-project-github-action
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/regenerate-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
env:
LATEST_VERSION: ${{ github.event.inputs.latestVersion }}
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v6
with:
delete-branch: true
branch: update-docs-github-action
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
run: |
Scripts/increment_version.sh ${{ github.event.inputs.newVersion }}
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v6
with:
delete-branch: true
branch: update-version-github-action
Expand Down
80 changes: 52 additions & 28 deletions Adyen.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions Adyen/Analytics/AnalyticsProvider/AnalyticsFlavor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// Copyright (c) 2023 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//

import Foundation

@_spi(AdyenInternal)
public enum AnalyticsFlavor {
case components(type: PaymentMethodType)
case dropIn(type: String = "dropin", paymentMethods: [String])

public var value: String {
switch self {
case .components:
return "components"
case .dropIn:
return "dropin"
}
}
}
60 changes: 32 additions & 28 deletions Adyen/Analytics/AnalyticsProvider/AnalyticsProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@ public struct AnalyticsConfiguration {

/// A Boolean value that determines whether analytics is enabled.
public var isEnabled = true

@_spi(AdyenInternal)
public var isTelemetryEnabled = true

@_spi(AdyenInternal)
public var context: TelemetryContext = .init()
public var context: AnalyticsContext = .init()

// MARK: - Initializers

Expand All @@ -28,20 +25,26 @@ public struct AnalyticsConfiguration {
}

@_spi(AdyenInternal)
/// Additional fields to be provided with a ``TelemetryRequest``
/// Additional fields to be provided with an ``InitialAnalyticsRequest``
public struct AdditionalAnalyticsFields {
/// The amount of the payment
public let amount: Amount?

public let sessionId: String?

public init(amount: Amount?, sessionId: String?) {
self.amount = amount
self.sessionId = sessionId
}
}

@_spi(AdyenInternal)
public protocol AnalyticsProviderProtocol: TelemetryTrackerProtocol {

var checkoutAttemptId: String? { get }
public protocol AnalyticsProviderProtocol {

func fetchAndCacheCheckoutAttemptIdIfNeeded()
/// Sends the initial data and retrieves the checkout attempt id as a response.
func sendInitialAnalytics(with flavor: AnalyticsFlavor, additionalFields: AdditionalAnalyticsFields?)

var additionalFields: (() -> AdditionalAnalyticsFields)? { get }
var checkoutAttemptId: String? { get }
}

internal final class AnalyticsProvider: AnalyticsProviderProtocol {
Expand All @@ -51,8 +54,7 @@ internal final class AnalyticsProvider: AnalyticsProviderProtocol {
internal let apiClient: APIClientProtocol
internal let configuration: AnalyticsConfiguration
internal private(set) var checkoutAttemptId: String?
internal var additionalFields: (() -> AdditionalAnalyticsFields)?
private let uniqueAssetAPIClient: UniqueAssetAPIClient<CheckoutAttemptIdResponse>
private let uniqueAssetAPIClient: UniqueAssetAPIClient<InitialAnalyticsResponse>

// MARK: - Initializers

Expand All @@ -62,32 +64,34 @@ internal final class AnalyticsProvider: AnalyticsProviderProtocol {
) {
self.apiClient = apiClient
self.configuration = configuration
self.uniqueAssetAPIClient = UniqueAssetAPIClient<CheckoutAttemptIdResponse>(apiClient: apiClient)
self.uniqueAssetAPIClient = UniqueAssetAPIClient<InitialAnalyticsResponse>(apiClient: apiClient)
}

// MARK: - Internal

internal func fetchAndCacheCheckoutAttemptIdIfNeeded() {
fetchCheckoutAttemptId { _ in /* Do nothing, the point is to trigger the fetching and cache the value */ }
}

internal func fetchCheckoutAttemptId(completion: @escaping (String?) -> Void) {
internal func sendInitialAnalytics(with flavor: AnalyticsFlavor, additionalFields: AdditionalAnalyticsFields?) {
guard configuration.isEnabled else {
checkoutAttemptId = "do-not-track"
completion(checkoutAttemptId)
return
}

let analyticsData = AnalyticsData(flavor: flavor,
additionalFields: additionalFields,
context: configuration.context)

let checkoutAttemptIdRequest = CheckoutAttemptIdRequest()
let initialAnalyticsRequest = InitialAnalyticsRequest(data: analyticsData)

uniqueAssetAPIClient.perform(checkoutAttemptIdRequest) { [weak self] result in
switch result {
case let .success(response):
self?.checkoutAttemptId = response.identifier
completion(response.identifier)
case .failure:
completion(nil)
}
uniqueAssetAPIClient.perform(initialAnalyticsRequest) { [weak self] result in
self?.saveCheckoutAttemptId(from: result)
}
}

private func saveCheckoutAttemptId(from result: Result<InitialAnalyticsResponse, Error>) {
switch result {
case let .success(response):
checkoutAttemptId = response.checkoutAttemptId
case .failure:
checkoutAttemptId = nil
}
}
}
60 changes: 0 additions & 60 deletions Adyen/Analytics/AnalyticsProvider/TelemetryTracker.swift

This file was deleted.

33 changes: 33 additions & 0 deletions Adyen/Analytics/Models/AdyenAnalytics.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Copyright (c) 2023 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//

import Foundation

@_spi(AdyenInternal)
/// Used as a singleton to update the sessionId
public final class AnalyticsForSession {

/// Needed to be able to determine if using session
public static var sessionId: String?

private init() { /* Private empty init */ }
}

@_spi(AdyenInternal)
/// A protocol that defines the events that can occur under Checkout Analytics.
public protocol AnalyticsEvent: Encodable {
var timestamp: TimeInterval { get }

var component: String { get }
}

@_spi(AdyenInternal)
public extension AnalyticsEvent {

var timestamp: TimeInterval {
Date().timeIntervalSince1970
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import UIKit
///
/// Used to e.g. override the version + platform from within the Flutter SDK
@_spi(AdyenInternal)
public struct TelemetryContext {
public struct AnalyticsContext {

internal let version: String
internal let platform: Platform
Expand All @@ -26,7 +26,7 @@ public struct TelemetryContext {
}

@_spi(AdyenInternal)
public extension TelemetryContext {
public extension AnalyticsContext {

enum Platform: String {
case iOS = "ios"
Expand All @@ -35,7 +35,7 @@ public extension TelemetryContext {
}
}

internal struct TelemetryData: Encodable {
internal struct AnalyticsData: Encodable {

// MARK: - Properties

Expand Down Expand Up @@ -64,6 +64,8 @@ internal struct TelemetryData: Encodable {
return identifier + String(UnicodeScalar(UInt8(value)))
}
}()

internal let deviceModel = UIDevice.current.model

internal let systemVersion = UIDevice.current.systemVersion

Expand All @@ -79,19 +81,20 @@ internal struct TelemetryData: Encodable {

internal var amount: Amount?

internal var sessionId: String?

internal var paymentMethods: [String] = []

internal let component: String

// MARK: - Initializers

internal init(
flavor: TelemetryFlavor,
amount: Amount?,
context: TelemetryContext
) {
internal init(flavor: AnalyticsFlavor,
additionalFields: AdditionalAnalyticsFields?,
context: AnalyticsContext) {
self.flavor = flavor.value
self.amount = amount
self.amount = additionalFields?.amount
self.sessionId = additionalFields?.sessionId

self.version = context.version
self.platform = context.platform.rawValue
Expand All @@ -102,8 +105,6 @@ internal struct TelemetryData: Encodable {
self.component = type
case let .components(type):
self.component = type.rawValue
default:
self.component = ""
}
}
}
30 changes: 30 additions & 0 deletions Adyen/Analytics/Models/AnalyticsEventError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// Copyright (c) 2023 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//

import Foundation

@_spi(AdyenInternal)
/// Represents an error in the analytics scheme that indicates the flow was interrupted due to an error in the SDK.
public struct AnalyticsEventError: AnalyticsEvent {

public var component: String

public var type: ErrorType

public var code: String?

public var message: String?

public enum ErrorType: String, Encodable {
case network = "Network"
case implementation = "Implementation"
case `internal` = "Internal"
case api = "ApiError"
case sdk = "SdkError"
case thirdParty = "ThirdParty"
case generic = "Generic"
}
}
Loading

0 comments on commit 8b48062

Please sign in to comment.