Skip to content

Commit

Permalink
Merge pull request #71 from checkout/develop
Browse files Browse the repository at this point in the history
Release 3.4.2
  • Loading branch information
harry-brown-cko authored May 10, 2021
2 parents e164e36 + ee5ac4b commit c696005
Show file tree
Hide file tree
Showing 45 changed files with 1,977 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cache:
directories:
- Carthage
script:
- pod install --project-directory='iOS Example Frame'
- pod install --project-directory='iOS Example Frame' --repo-update
- xcodebuild test -workspace 'iOS Example Frame/iOS Example Frame.xcworkspace' -scheme 'Frames-Unit-Tests' -destination 'OS=13.5,name=iPhone 11'
- xcodebuild build -project 'iOS Example Frame SPM/iOS Example Frame SPM.xcodeproj' -scheme 'iOS Example Frame' -destination 'OS=13.5,name=iPhone 11'
- carthage update --cache-builds --platform iOS --use-xcframeworks
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.

#### 3.x Releases

## [3.4.2](https://github.com/checkout/frames-ios/releases/tag/3.4.2)

Released on 2021-05-10.

#### Fixed

* App Store distribution issues for Carthage apps that use Frames and PhoneNumberKit.

## [3.4.1](https://github.com/checkout/frames-ios/releases/tag/3.4.1)

Released on 2021-04-13.
Expand Down
3 changes: 2 additions & 1 deletion Frames.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "Frames"
s.version = "3.4.1"
s.version = "3.4.2"
s.summary = "Checkout API Client, Payment Form UI and Utilities in Swift"
s.description = <<-DESC
Checkout API Client and Payment Form Utilities in Swift.
Expand All @@ -19,6 +19,7 @@ Pod::Spec.new do |s|

s.dependency 'PhoneNumberKit', '~> 3.3.0'
s.dependency 'Alamofire', '~> 5.4.0'
s.dependency 'CheckoutEventLoggerKit', '~> 1.0.2'

s.test_spec do |t|
t.source_files = 'Tests/**/*.swift'
Expand Down
5 changes: 3 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.4.0"),
.package(url: "https://github.com/marmelroy/PhoneNumberKit.git", from: "3.3.0")
.package(url: "https://github.com/marmelroy/PhoneNumberKit.git", from: "3.3.0"),
.package(name: "CheckoutEventLoggerKit", url: "https://github.com/checkout/checkout-event-logger-ios-framework.git", from: "1.0.2")
],
targets: [
.target(
name: "Frames",
dependencies: ["Alamofire", "PhoneNumberKit"],
dependencies: ["Alamofire", "PhoneNumberKit", "CheckoutEventLoggerKit"],
path: "Source",
exclude: ["Suppporting Files/Info.plist"],
resources: [
Expand Down
3 changes: 2 additions & 1 deletion Source/CheckoutAPIClient+Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Foundation

extension CheckoutAPIClient {
enum Constants {
static let version = "3.4.1"
static let productName = "frames-ios-sdk"
static let version = "3.4.2"
}
}
57 changes: 55 additions & 2 deletions Source/CheckoutAPIClient.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Foundation
import Alamofire
import CheckoutEventLoggerKit
import UIKit

/// Checkout API Client
/// used to call the api endpoint of Checkout API available with your public key
Expand All @@ -13,6 +15,9 @@ public class CheckoutAPIClient {
/// Environment (sandbox or live)
let environment: Environment

/// Checkout Logger
let logger: CheckoutEventLogging

/// headers used for the requests
private var headers: HTTPHeaders {
return ["Authorization": self.publicKey,
Expand All @@ -26,12 +31,31 @@ public class CheckoutAPIClient {
init(publicKey: String,
environment: Environment,
jsonEncoder: JSONEncoder,
jsonDecoder: JSONDecoder) {
jsonDecoder: JSONDecoder,
logger: CheckoutEventLogging) {

self.publicKey = publicKey
self.environment = environment
self.jsonEncoder = jsonEncoder
self.jsonDecoder = jsonDecoder
self.logger = logger
}

convenience init(publicKey: String,
environment: Environment,
jsonEncoder: JSONEncoder,
jsonDecoder: JSONDecoder,
logger: CheckoutEventLogging,
remoteProcessorMetadata: RemoteProcessorMetadata) {

logger.enableRemoteProcessor(environment: environment == .sandbox ? .sandbox : .production,
remoteProcessorMetadata: remoteProcessorMetadata)

self.init(publicKey: publicKey,
environment: environment,
jsonEncoder: jsonEncoder,
jsonDecoder: jsonDecoder,
logger: logger)
}

// MARK: - Initialization
Expand All @@ -52,10 +76,25 @@ public class CheckoutAPIClient {
let jsonEncoder = JSONEncoder()
jsonEncoder.keyEncodingStrategy = .convertToSnakeCase

let logger = CheckoutEventLogger(productName: CheckoutAPIClient.Constants.productName)

let appBundle = Foundation.Bundle.main
let appPackageName = appBundle.bundleIdentifier ?? "unavailableAppPackageName"
let appPackageVersion = appBundle.infoDictionary?["CFBundleShortVersionString"] as? String ?? "unavailableAppPackageVersion"

let uiDevice = UIKit.UIDevice.current

let remoteProcessorMetadata = CheckoutAPIClient.buildRemoteProcessorMetadata(environment: environment,
appPackageName: appPackageName,
appPackageVersion: appPackageVersion,
uiDevice: uiDevice)

self.init(publicKey: publicKey,
environment: environment,
jsonEncoder: jsonEncoder,
jsonDecoder: jsonDecoder)
jsonDecoder: jsonDecoder,
logger: logger,
remoteProcessorMetadata: remoteProcessorMetadata)
}

// MARK: - Methods
Expand Down Expand Up @@ -289,4 +328,18 @@ public class CheckoutAPIClient {
}
}

static func buildRemoteProcessorMetadata(environment: Environment,
appPackageName: String,
appPackageVersion: String,
uiDevice: UIDevice) -> RemoteProcessorMetadata {

return RemoteProcessorMetadata(productIdentifier: CheckoutAPIClient.Constants.productName,
productVersion: CheckoutAPIClient.Constants.version,
environment: environment.rawValue,
appPackageName: appPackageName,
appPackageVersion: appPackageVersion,
deviceName: uiDevice.modelName,
platform: "iOS",
osVersion: uiDevice.systemVersion)
}
}
46 changes: 46 additions & 0 deletions Source/Core/Logging/FramesLogEvent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import Foundation
import CheckoutEventLoggerKit

enum FramesLogEvent {

case paymentFormPresented

var event: Event {
Event(typeIdentifier: "com.checkout.frames-mobile-sdk.\(typeIdentifier)",
time: time,
monitoringLevel: monitoringLevel,
properties: properties)
}

var providingMetadata: [String: String] {
switch self {
case .paymentFormPresented:
return [:]
}
}

private var typeIdentifier: String {
switch self {
case .paymentFormPresented:
return "payment_form_presented"
}
}

private var time: Date {
Date()
}

private var monitoringLevel: MonitoringLevel {
switch self {
case .paymentFormPresented:
return .info
}
}

private var properties: [String: AnyCodable] {
switch self {
case .paymentFormPresented:
return [:]
}
}
}
14 changes: 14 additions & 0 deletions Source/Core/Logging/LoggingExtensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import CheckoutEventLoggerKit

extension CheckoutEventLogging {

func log(_ framesLogEvent: FramesLogEvent) {

framesLogEvent.providingMetadata.forEach { (metadata, value) in

self.add(metadata: metadata, value: value)
}

self.log(event: framesLogEvent.event)
}
}
7 changes: 3 additions & 4 deletions Source/Extensions/StringExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import UIKit

extension String {

private func getBundle(forClass: AnyClass) -> Bundle {
private func getBundle(forClass: AnyClass) -> Foundation.Bundle {
#if SWIFT_PACKAGE
let baseBundle = Bundle.module
#else
let baseBundle = Bundle(for: forClass)
let baseBundle = Foundation.Bundle(for: forClass)
#endif
let path = baseBundle.path(forResource: "Frames", ofType: "bundle")
return path == nil ? baseBundle : Bundle(path: path!)!
return path == nil ? baseBundle : Foundation.Bundle(path: path!)!
}

func localized(forClass: AnyClass, comment: String = "") -> String {
Expand All @@ -22,5 +22,4 @@ extension String {
let bundle = getBundle(forClass: forClass)
return UIImage(named: self, in: bundle, compatibleWith: nil) ?? UIImage()
}

}
27 changes: 27 additions & 0 deletions Source/Extensions/UIDeviceExtensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import UIKit

protocol UIDevice {

var modelName: String { get }
var systemVersion: String { get }
}

extension UIKit.UIDevice: UIDevice {

var modelName: String {
// added simulator support from https://gist.github.com/SergLam/50c0e400877d76c499c2649b109b3890
#if targetEnvironment(simulator)
if let identifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
return identifier
}
#endif

var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
return machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
}
}
2 changes: 1 addition & 1 deletion Source/UI/Controllers/AddressViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class AddressViewController: UIViewController,
}

/// Returns a newly initialized view controller with the nib file in the specified bundle.
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Foundation.Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}

Expand Down
12 changes: 10 additions & 2 deletions Source/UI/Controllers/CardViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public class CardViewController: UIViewController,

var topConstraint: NSLayoutConstraint?

private var suppressNextLog = false

// MARK: - Initialization

/// Returns a newly initialized view controller with the cardholder's name and billing details
Expand All @@ -56,7 +58,7 @@ public class CardViewController: UIViewController,
}

/// Returns a newly initialized view controller with the nib file in the specified bundle.
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Foundation.Bundle?) {
cardHolderNameState = .required
billingDetailsState = .required
cardView = CardView(cardHolderNameState: cardHolderNameState, billingDetailsState: billingDetailsState)
Expand Down Expand Up @@ -97,7 +99,6 @@ public class CardViewController: UIViewController,
setInitialDate()

self.automaticallyAdjustsScrollViewInsets = false

}

/// Notifies the view controller that its view is about to be added to a view hierarchy.
Expand All @@ -107,6 +108,12 @@ public class CardViewController: UIViewController,
registerKeyboardHandlers(notificationCenter: notificationCenter,
keyboardWillShow: #selector(keyboardWillShow),
keyboardWillHide: #selector(keyboardWillHide))

if suppressNextLog {
suppressNextLog = false
} else {
checkoutApiClient?.logger.log(.paymentFormPresented)
}
}

/// Notifies the view controller that its view is about to be removed from a view hierarchy.
Expand Down Expand Up @@ -154,6 +161,7 @@ public class CardViewController: UIViewController,

@objc func onTapAddressView() {
navigationController?.pushViewController(addressViewController, animated: true)
suppressNextLog = true
}

@objc func onTapDoneCardButton() {
Expand Down
2 changes: 1 addition & 1 deletion Source/UI/Controllers/ThreedsWebViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class ThreedsWebViewController: UIViewController,
}

/// Returns a newly initialized view controller with the nib file in the specified bundle.
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Foundation.Bundle?) {
successUrl = ""
failUrl = ""
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
Expand Down
21 changes: 21 additions & 0 deletions Tests/Core/CheckoutAPIClientTests.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import XCTest
import UIKit
@testable import Frames
import CheckoutEventLoggerKit

import Mockingjay

Expand Down Expand Up @@ -120,4 +122,23 @@ class CheckoutAPIClientTests: XCTestCase {
wait(for: [expectation], timeout: 1.0)
}

func testRemoteProcessorMetadata() {
let stubUIDevice = StubUIDevice(modelName: "modelName", systemVersion: "systemVersion")

let subject = CheckoutAPIClient.buildRemoteProcessorMetadata(environment: .sandbox,
appPackageName: "appPackageName",
appPackageVersion: "appPackageVersion",
uiDevice: stubUIDevice)

let expected = RemoteProcessorMetadata(productIdentifier: CheckoutAPIClient.Constants.productName,
productVersion: CheckoutAPIClient.Constants.version,
environment: "sandbox",
appPackageName: "appPackageName",
appPackageVersion: "appPackageVersion",
deviceName: "modelName",
platform: "iOS",
osVersion: "systemVersion")

XCTAssertEqual(subject, expected)
}
}
Loading

0 comments on commit c696005

Please sign in to comment.