Skip to content

Commit

Permalink
Merge branch 'main' into config-loader-dedupe
Browse files Browse the repository at this point in the history
  • Loading branch information
scannillo committed Jul 16, 2024
2 parents 97da526 + aa394b1 commit 3c211f6
Show file tree
Hide file tree
Showing 38 changed files with 351 additions and 115 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Lint
on: [pull_request]
concurrency:
group: lint-${{ github.event.number }}
cancel-in-progress: true
jobs:
swiftlint:
name: SwiftLint
runs-on: macOS-14-xlarge
steps:
- name: Check out repository
uses: actions/checkout@v3
- name: Use Xcode 15.0.1
run: sudo xcode-select -switch /Applications/Xcode_15.0.1.app
- name: Install SwiftLint
run: brew install swiftlint
- name: Run SwiftLint
run: swiftlint --strict
106 changes: 106 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Reference: https://github.com/realm/SwiftLint
# Required Swiftlint Version
# swiftlint_version: 0.55.1

# Paths to include in lint
included:
- Sources/BraintreeCore

excluded:
- Sources/BraintreeCore/BTAPIPinnedCertificates.swift

disabled_rules:
- todo
- type_name # tests will have the format <SUT>_Tests
- xctfail_message
- blanket_disable_command
- non_optional_string_data_conversion
- attributes
- multiline_function_chains

opt_in_rules:
- array_init
- closure_end_indentation
- closure_spacing
- collection_alignment
- colon # promote to error
- convenience_type
- discouraged_object_literal
- empty_collection_literal
- empty_count
- empty_string
- enum_case_associated_values_count
- fatal_error_message
- first_where
- force_unwrapping
- implicitly_unwrapped_optional
- indentation_width
- last_where
- legacy_random
- literal_expression_end_indentation
- multiline_arguments
- multiline_function_chains
- multiline_literal_brackets
- multiline_parameters
- multiline_parameters_brackets
- operator_usage_whitespace
- overridden_super_call
- pattern_matching_keywords
- prefer_self_type_over_type_of_self
- redundant_nil_coalescing
- redundant_type_annotation
- strict_fileprivate
- toggle_bool
- trailing_closure
- unneeded_parentheses_in_closure_argument
- vertical_whitespace_closing_braces
- yoda_condition

custom_rules:
array_constructor:
name: "Array/Dictionary initializer"
regex: '[let,var] .+ = (\[.+\]\(\))'
capture_group: 1
message: "Use explicit type annotation when initializing empty arrays and dictionaries"
severity: warning
space_after_main_type:
name: "No space after main type"
regex: '(class|struct|extension)((?-s)\s.*\{$\n)(?!^\s*$)'
message: "Empty line required after main declarations"
severity: warning

force_cast: warning
force_try: warning
function_body_length:
warning: 60

legacy_hashing: error

identifier_name:
excluded:
- i
- id
- x
- y
- z

indentation_width:
indentation_width: 4

line_length:
warning: 140
ignores_urls: true
ignores_comments: true

multiline_arguments:
first_argument_location: next_line
only_enforce_after_first_closure_on_first_line: true

private_over_fileprivate:
validate_extensions: true

trailing_whitespace:
ignores_empty_lines: true

vertical_whitespace:
max_empty_lines: 2
2 changes: 1 addition & 1 deletion Braintree.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "Braintree"
s.version = "6.22.0"
s.version = "6.23.0"
s.summary = "Braintree iOS SDK: Helps you accept card and alternative payments in your iOS app."
s.description = <<-DESC
Braintree is a full-stack payments platform for developers
Expand Down
21 changes: 21 additions & 0 deletions Braintree.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2240,6 +2240,7 @@
570B9385285397520041BAFE /* Frameworks */,
570B9386285397520041BAFE /* Headers */,
570B93A8285397520041BAFE /* Resources */,
BE676C532C417B8F000A6579 /* Swiftlint */,
);
buildRules = (
);
Expand Down Expand Up @@ -3157,6 +3158,26 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
BE676C532C417B8F000A6579 /* Swiftlint */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = Swiftlint;
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "#!/bin/sh\n\nif test -d \"/opt/homebrew/bin/\"; then\n PATH=\"/opt/homebrew/bin/:${PATH}\"\nfi\n\nexport PATH\n\nif which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
showEnvVarsInLog = 0;
};
CDAB67F3BC5BE564FCFFD6BC /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Braintree iOS SDK Release Notes

## unreleased
## 6.23.0 (2024-07-15)
* BraintreeShopperInsights (BETA)
* Add error when using an invalid authorization type
* BraintreeCore
* Update `URLOpener.openURL(_:completionHandler:)` protocol method to fix method signature change in Xcode 16 beta 3 (fixes #1359)
* BraintreeThreeDSecure
* Fix bug to conditionally unwrap `customFields` - this caused an error when this value was not set on `BTThreeDSecureRequest`

## 6.22.0 (2024-07-02)
* BraintreeThreeDSecure
Expand Down
10 changes: 10 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ This document outlines development practices that we follow while developing thi

The included demo app utilizes a [sandbox sample merchant server](https://braintree-sample-merchant.herokuapp.com) hosted on Heroku.

## SwiftLint

Ensure that you have [SwiftLint](https://github.com/realm/SwiftLint) installed as we utilize it within our project.

To install via [Homebrew](https://brew.sh/) run:
```
brew install swiftlint
```
Our Xcode workspace has a `Run Phase` which integrates in `SwiftLint` so the only prerequisite is installing via `Homebrew`.

## Tests

Each module has a corresponding unit test target. These can be run individually, or all at once via the `UnitTests` scheme.
Expand Down
6 changes: 0 additions & 6 deletions Demo/Application/Features/ThreeDSecureViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,6 @@ class ThreeDSecureViewController: PaymentButtonBaseViewController {
private func createThreeDSecureRequest(with nonce: String) -> BTThreeDSecureRequest {
let request = BTThreeDSecureRequest()

let customFields = [
"test" : "test",
"test1": "test1",
]

request.customFields = customFields
request.threeDSecureRequestDelegate = self
request.amount = 10.32
request.nonce = nonce
Expand Down
4 changes: 2 additions & 2 deletions Demo/Application/Supporting Files/Braintree-Demo-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>6.22.0</string>
<string>6.23.0</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
Expand All @@ -56,7 +56,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>6.22.0</string>
<string>6.23.0</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>com.braintreepayments.Demo.payments</string>
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,12 @@ Versions 4.9.6 and below use outdated SSL certificates and are unsupported.

## Demo

1. Our Xcode project uses SwiftLint. To ensure you have it installed see [DEVELOPMENT.md](https://github.com/braintree/braintree_ios/blob/main/DEVELOPMENT.md#swiftlint)
1. Run `pod install`
* There is a known M1 mac issue with CocoaPods. See [this solution](https://github.com/CocoaPods/CocoaPods/issues/10220#issuecomment-730963835) to resolve `ffi` dependency issues.
2. Resolve the Swift Package Manager packages if needed: `File` > `Packages` > `Resolve Package Versions` or by running `swift package resolve` in Terminal
3. Open `Braintree.xcworkspace` in Xcode
4. Select the `Demo` scheme, and then run
1. Resolve the Swift Package Manager packages if needed: `File` > `Packages` > `Resolve Package Versions` or by running `swift package resolve` in Terminal
1. Open `Braintree.xcworkspace` in Xcode
1. Select the `Demo` scheme, and then run

Xcode 15.0+ is required to run the demo app.

Expand Down
8 changes: 7 additions & 1 deletion Sources/BraintreeCore/Analytics/BTAnalyticsService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ class BTAnalyticsService: Equatable {

// MARK: - Internal Properties

// swiftlint:disable force_unwrapping
/// The FPTI URL to post all analytic events.
static let url = URL(string: "https://api.paypal.com")!
// swiftlint:enable force_unwrapping

/// The HTTP client for communication with the analytics service endpoint. Exposed for testing.
var http: BTHTTP?
Expand Down Expand Up @@ -131,7 +133,11 @@ class BTAnalyticsService: Equatable {
if await !BTAnalyticsService.events.isEmpty {
do {
let configuration = try await apiClient.fetchConfiguration()
let postParameters = await createAnalyticsEvent(config: configuration, sessionID: apiClient.metadata.sessionID, events: Self.events.allValues)
let postParameters = await createAnalyticsEvent(
config: configuration,
sessionID: apiClient.metadata.sessionID,
events: Self.events.allValues
)
http?.post("v1/tracking/batch/events", parameters: postParameters) { _, _, _ in }
await Self.events.removeAll()
} catch {
Expand Down
11 changes: 7 additions & 4 deletions Sources/BraintreeCore/Analytics/FPTIBatchData.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import UIKit

// swiftlint:disable nesting
/// The POST body for a batch upload of FPTI events
struct FPTIBatchData: Codable {

let events: [EventsContainer] // Single-element "events" array required by FPTI formatting

init(metadata: Metadata, events fptiEvents: [Event]?) {
self.events = [EventsContainer(
metadata: metadata,
fptiEvents: fptiEvents ?? []
)]
self.events = [
EventsContainer(
metadata: metadata,
fptiEvents: fptiEvents ?? []
)
]
}

struct EventsContainer: Codable {
Expand Down
8 changes: 3 additions & 5 deletions Sources/BraintreeCore/Authorization/BTClientToken.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Foundation
/// An authorization string used to initialize the Braintree SDK
@_documentation(visibility: private)
@objcMembers public class BTClientToken: NSObject, NSCoding, NSCopying, ClientAuthorization {

// NEXT_MAJOR_VERSION (v7): properties exposed for Objective-C interoperability + Drop-in access.
// Once the entire SDK is in Swift, determine if we want public properties to be internal and
// what we can make internal without breaking the Drop-in.
Expand Down Expand Up @@ -38,8 +38,7 @@ import Foundation
// Client token must be decoded first because the other values are retrieved from it
self.json = try Self.decodeClientToken(clientToken)

guard let authorizationFingerprint = json["authorizationFingerprint"].asString(),
!authorizationFingerprint.isEmpty else {
guard let authorizationFingerprint = json["authorizationFingerprint"].asString(), !authorizationFingerprint.isEmpty else {
throw BTClientTokenError.invalidAuthorizationFingerprint
}

Expand Down Expand Up @@ -113,8 +112,7 @@ import Foundation
// MARK: - NSObject override

public override func isEqual(_ object: Any?) -> Bool {
guard object is BTClientToken,
let otherToken = object as? BTClientToken else {
guard object is BTClientToken, let otherToken = object as? BTClientToken else {
return false
}

Expand Down
2 changes: 2 additions & 0 deletions Sources/BraintreeCore/Authorization/BTClientTokenError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public enum BTClientTokenError: Error, CustomNSError, LocalizedError, Equatable
}
}

// swiftlint:disable line_length
public var errorDescription: String? {
switch self {
case .invalidAuthorizationFingerprint:
Expand All @@ -51,4 +52,5 @@ public enum BTClientTokenError: Error, CustomNSError, LocalizedError, Equatable
return "Failed to decode client token. \(description)"
}
}
// swiftlint:enable line_length
}
6 changes: 3 additions & 3 deletions Sources/BraintreeCore/Authorization/TokenizationKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ class TokenizationKey: ClientAuthorization {
guard tokenizationKey.range(of: pattern, options: .regularExpression) != nil else { return nil }

let tokenizationKeyParts = tokenizationKey.split(separator: "_", maxSplits: 3)
let environment: String = String(tokenizationKeyParts[0])
let merchantID: String = String(tokenizationKeyParts[2])
let environment = String(tokenizationKeyParts[0])
let merchantID = String(tokenizationKeyParts[2])

var components: URLComponents = URLComponents()
var components = URLComponents()
components.scheme = environment == "development" ? "http" : "https"

guard let host = host(for: environment) else { return nil }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ public enum TokenizationKeyError: Int, Error, CustomNSError, LocalizedError, Equ
}
}
}

Loading

0 comments on commit 3c211f6

Please sign in to comment.