Skip to content

Commit

Permalink
Merge pull request #332 from stripe/release-4.0.0
Browse files Browse the repository at this point in the history
Release 4.0.0
  • Loading branch information
bric-stripe authored Oct 31, 2024
2 parents 76747b4 + ea7265e commit b22040e
Show file tree
Hide file tree
Showing 849 changed files with 445,343 additions and 100,391 deletions.
54 changes: 53 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,60 @@ of each release can be found in the [Support Lifecycle](SUPPORT.md).

If you are using CocoaPods, update your Podfile:
```
pod 'StripeTerminal', '~> 3.0'
pod 'StripeTerminal', '~> 4.0'
```

# 4.0.0 2024-10-31
4.0.0 includes breaking changes in both symbols and behavior. See the [migration guide](https://stripe.com/docs/terminal/references/sdk-migration-guide) for more details.

* Built with Xcode 16.0, Swift version 6.0.
* Update: Minimum deployment target updated from iOS 13.0 to iOS 14.0.

### New Features
* [Mail order / telephone order (MOTO)](https://docs.stripe.com/terminal/features/mail-telephone-orders/overview) payment support for smart readers.
- Contact Stripe support to enable this feature on your account.

* Global [card saving after payment](https://docs.stripe.com/terminal/features/saving-cards/save-after-payment) support by updating customer consent capture. The following breaking changes are required:
- A valid `allowRedisplay` value is now required to be set in `collectConfiguration` when using `setupFutureUsage` for `SCPTerminal`'s `collectPaymentMethod`.
- Removed the `customerConsentCollected` parameter from `SCPTerminal`'s `collectSetupIntentPaymentMethod` and replaced it with `allowRedisplay`.

## ⚠️ Breaking changes required

### Reader discovery
* New: Added a new enum value `discovering` to [`SCPConnectionStatus`](https://stripe.dev/stripe-terminal-ios/docs/Enums/SCPConnectionStatus.html) to represent when discovery is running.
* Update: Subsequent calls to `SCPTerminal`'s `discoverReaders:delegate:completion:` cancel all previously queued discovery operations. Only one discovery operation can run at any given time; all other discovery attempts will fail with `SCPErrorCanceledDueToIntegrationError`.
* Update: Internet and Tap to Pay discovery will now call the [`discoverReaders`](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc(cs)SCPTerminal(im)discoverReaders:delegate:completion:) completion block when the operation completes since these are not long running discovery operations.

### Reader connection
* Update: There is now a single [`connectReader`](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc(cs)SCPTerminal(im)connectReader:delegate:connectionConfig:completion:) call used for all connection methods. This replaces the previous methods: `connectBluetoothReader`, `connectInternetReader`, and `connectLocalMobileReader`.
- For mobile readers and Tap to Pay readers, the `ReaderDelegate` has been removed from the `connectReader` method as a parameter, and moved into the `connectionConfig`, replacing `autoReconnectionDelegate`. - For smart readers, the `InternetConnectionConfiguration` now also expects an `InternetReaderDelegate` to be passed in, which will alert your integration of reader disconnects.

* Update: [Auto reconnect on unexpected disconnect](https://docs.stripe.com/terminal/payments/connect-reader?terminal-sdk-platform=ios&reader-type=tap-to-pay#2.-automatically-attempt-reconnection) is now enabled by default for mobile and Tap to Pay readers.
* The `SCPReconnectionDelegate` has been removed and the methods have been moved to the common [`ReaderDelegate`](https://stripe.dev/stripe-terminal-ios/docs/Protocols/SCPReaderDelegate.html).
* Update: The method for handling reader disconnects has changed.
* Removed `terminal:didReportUnexpectedReaderDisconnect:` from the `SCPTerminalDelegate`. Use [`reader:didDisconnect:`](https://stripe.dev/stripe-terminal-ios/docs/Protocols/SCPReaderDelegate.html#/c:objc(pl)SCPReaderDelegate(im)reader:didDisconnect:) to be informed of reader disconnects.
* When auto-reconnect on unexpected disconnect is enabled, both [`-readerDidFailReconnect:`](https://stripe.dev/stripe-terminal-ios/docs/4.0.0/Protocols/SCPReaderDelegate.html#/c:objc(pl)SCPReaderDelegate(im)readerDidFailReconnect:) and [`reader:didDisconnect:`](https://stripe.dev/stripe-terminal-ios/docs/4.0.0/Protocols/SCPReaderDelegate.html#/c:objc(pl)SCPReaderDelegate(im)reader:didDisconnect:) methods will be called if the SDK fails to reconnect to the reader and it becomes disconnected.

### Payment acceptance
* New: Added a new enum value `SCPCardPresentCaptureMethodManual` to [`SCPCardPresentCaptureMethod`](https://stripe.dev/stripe-terminal-ios/docs/Enums/SCPCardPresentCaptureMethod.html) for simplifying manual card capture without affecting automatic non-card payment capture.
* If you are interested in joining this private preview, please email [stripe-terminal-betas@stripe.com](mailto:stripe-terminal-betas@stripe.com).
* Update: `SCPTerminal`'s `confirmPaymentIntent:completion`, `confirmSetupIntent:completion`, and `confirmRefund:completion` operations now return `SCPCancelable`'s that allow you to cancel the operation in certain scenarios.
* Update: Calls to `SCPTerminal`'s `cancelPaymentIntent:completion` or `cancelSetupIntent:completion` will now cancel ongoing operations related to the specified intent.
* Update: [`SCPOfflineDelegate`](https://stripe.dev/stripe-terminal-ios/docs/Protocols/SCPOfflineDelegate.html) now conforms to `NSObject`.
* Update: `SCPPaymentIntentParameters` and `SCPSetupIntentParameters` now keep payment method types as values of the `SCPPaymentMethodType` enum rather than strings.
* Update: [`SCPSetupIntent.stripeId`](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPSetupIntent.html#/c:objc(cs)SCPSetupIntent(py)stripeId) is now `nullable` to be consistent with `SCPPaymentintent.stripeId`. The `SCPSetupIntent.stripeId` will continue to be present.

### Renaming
* Update: [`BluetoothReaderDelegate`](https://stripe.dev/stripe-terminal-ios/3.9.0/Protocols/SCPBluetoothReaderDelegate.html) has been renamed to [`MobileReaderDelegate`](https://stripe.dev/stripe-terminal-ios/Protocols/SCPMobileReaderDelegate.html).
* Update: In `SCPReaderSoftwareUpdate`, renamed `estimatedUpdateTime` to `durationEstimate`.
* Update: Renamed `SCPUpdateTimeEstimate` to `SCPUpdateDurationEstimate`.
* Update: Renamed "local mobile" and "apple built in" to "Tap To Pay" in all SDK types, function names, and error codes to align with Stripe branding for this functionality.

## Non-breaking changes
* Update: The [`SCPInternetDiscoveryConfiguration`](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPInternetDiscoveryConfiguration.html) now supports an optional `timeout` value, specifying the timeout in seconds for the discover readers request. If the online discovery attempt fails, the operation will automatically fall back to offline discovery if [offline mode](https://docs.stripe.com/terminal/features/operate-offline/overview?reader-type=internet) is enabled.
* Update: Improved accuracy of smart reader errors that are reported as `SCPError`. Errors that were previously reported as a `SCPErrorGenericReaderError` are now mapped to a more specific `SCPError` type.


# 3.9.1 2024-09-05
* Built with Xcode 15.2, Swift version 5.9.
* Fix [#325](https://github.com/stripe/stripe-terminal-ios/issues/325): Corrects the status of `Terminal.shared.paymentStatus` and `Terminal.shared.connectionStatus` after [automatically reconnecting](https://docs.stripe.com/terminal/payments/connect-reader?terminal-sdk-platform=ios&reader-type=bluetooth#handle-disconnects) to mobile readers during unexpected disconnects.
Expand Down
40 changes: 20 additions & 20 deletions Example/Example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
50225C402B4DACB300757FC6 /* StartReaderSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50225C3F2B4DACB300757FC6 /* StartReaderSettingsViewController.swift */; };
50225C5E2B508DFB00757FC6 /* Error+StripeTerminal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50225C5D2B508DFB00757FC6 /* Error+StripeTerminal.swift */; };
6F8BE0922177B403009511E5 /* DiscoveryMethodViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8BE0912177B403009511E5 /* DiscoveryMethodViewController.swift */; };
7BCA0C6739FF6C2E1B3AE86F /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F933CA536E7BD443088E6702 /* Pods_Example.framework */; };
A40E7CF027F64191005879C7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C16F40A72094F07C009CE87C /* Assets.xcassets */; };
A63E8431260D073B006CB90C /* CreateLocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A63E8430260D073B006CB90C /* CreateLocationViewController.swift */; };
A63E8435260D0A0D006CB90C /* SelectLocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A63E8434260D0A0D006CB90C /* SelectLocationViewController.swift */; };
Expand All @@ -58,7 +59,6 @@
C1DE30D721438E9900A3026F /* UIViewController+UIAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1DE30D121438E9800A3026F /* UIViewController+UIAlertController.swift */; };
C1DE30D821438E9900A3026F /* UIView+Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1DE30D221438E9800A3026F /* UIView+Layout.swift */; };
C1F78BDB2144F0830094BE37 /* CustomViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1F78BDA2144F0830094BE37 /* CustomViews.swift */; };
D1823934E4A82B04B4DB9896 /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6C5EBEE90C4E3204BD10FFF /* Pods_Example.framework */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
Expand Down Expand Up @@ -100,17 +100,17 @@
390B937A2BED7C1800557850 /* CollectDataViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectDataViewController.swift; sourceTree = "<group>"; };
3936853D28860BDE0026A906 /* CaptureMethod+String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CaptureMethod+String.swift"; sourceTree = "<group>"; };
3959705F2A8D85830015F0F3 /* LocationStub.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationStub.swift; sourceTree = "<group>"; };
4FD82F87B0169B182DE08E4B /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = "<group>"; };
50225C3F2B4DACB300757FC6 /* StartReaderSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartReaderSettingsViewController.swift; sourceTree = "<group>"; };
50225C5D2B508DFB00757FC6 /* Error+StripeTerminal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error+StripeTerminal.swift"; sourceTree = "<group>"; };
5F298C7CAAC76F0FE28E79E3 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = "<group>"; };
68331A81F431D3EB50C6D085 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = "<group>"; };
6F8BE0912177B403009511E5 /* DiscoveryMethodViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoveryMethodViewController.swift; sourceTree = "<group>"; };
A63E8430260D073B006CB90C /* CreateLocationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateLocationViewController.swift; sourceTree = "<group>"; };
A63E8434260D0A0D006CB90C /* SelectLocationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectLocationViewController.swift; sourceTree = "<group>"; };
A63E8456260D23C9006CB90C /* StripeCountries.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StripeCountries.swift; sourceTree = "<group>"; };
AA568CD02A9D413900B9605C /* StartSetupIntentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartSetupIntentViewController.swift; sourceTree = "<group>"; };
B3C24C6B23285BF6003271BD /* ifaddrs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ifaddrs.swift; sourceTree = "<group>"; };
B3C53B8B23286DA9003A707B /* Example-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Example-Bridging-Header.h"; sourceTree = "<group>"; };
B6C5EBEE90C4E3204BD10FFF /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C151C7A521605B6200FC206F /* UpdateReaderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateReaderViewController.swift; sourceTree = "<group>"; };
C152F77B214A18C00078BD07 /* StripeCurrencies.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StripeCurrencies.swift; sourceTree = "<group>"; };
C16651B621963C51006EFACF /* APIClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = APIClient.swift; sourceTree = "<group>"; };
Expand All @@ -130,7 +130,7 @@
C1DE30D121438E9800A3026F /* UIViewController+UIAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+UIAlertController.swift"; sourceTree = "<group>"; };
C1DE30D221438E9800A3026F /* UIView+Layout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Layout.swift"; sourceTree = "<group>"; };
C1F78BDA2144F0830094BE37 /* CustomViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomViews.swift; sourceTree = "<group>"; };
D0BA0AF20D590A047F38D5AE /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = "<group>"; };
F933CA536E7BD443088E6702 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -139,18 +139,18 @@
buildActionMask = 2147483647;
files = (
022FB25B245868EF00F4C321 /* StripeTerminal.xcframework in Frameworks */,
D1823934E4A82B04B4DB9896 /* Pods_Example.framework in Frameworks */,
7BCA0C6739FF6C2E1B3AE86F /* Pods_Example.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
1F9017D3F9880088EE567B8C /* Pods */ = {
9AB770F8BEE42F0193407BF9 /* Pods */ = {
isa = PBXGroup;
children = (
D0BA0AF20D590A047F38D5AE /* Pods-Example.debug.xcconfig */,
4FD82F87B0169B182DE08E4B /* Pods-Example.release.xcconfig */,
68331A81F431D3EB50C6D085 /* Pods-Example.debug.xcconfig */,
5F298C7CAAC76F0FE28E79E3 /* Pods-Example.release.xcconfig */,
);
name = Pods;
path = Pods;
Expand All @@ -162,7 +162,7 @@
C16F409F2094F07B009CE87C /* Example */,
EE087B524FD387212EBE036B /* Frameworks */,
C16F409E2094F07B009CE87C /* Products */,
1F9017D3F9880088EE567B8C /* Pods */,
9AB770F8BEE42F0193407BF9 /* Pods */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -236,7 +236,7 @@
isa = PBXGroup;
children = (
022FB25A245868EF00F4C321 /* StripeTerminal.xcframework */,
B6C5EBEE90C4E3204BD10FFF /* Pods_Example.framework */,
F933CA536E7BD443088E6702 /* Pods_Example.framework */,
);
name = Frameworks;
sourceTree = "<group>";
Expand All @@ -248,12 +248,12 @@
isa = PBXNativeTarget;
buildConfigurationList = C16F40AF2094F07C009CE87C /* Build configuration list for PBXNativeTarget "Example" */;
buildPhases = (
FDB3870A5F628D73748E5225 /* [CP] Check Pods Manifest.lock */,
7C8C6C314F349CEDD997FF26 /* [CP] Check Pods Manifest.lock */,
C16F40992094F07B009CE87C /* Sources */,
C16F409B2094F07B009CE87C /* Resources */,
0DE2ACED4D7F3843500B5F14 /* Frameworks */,
02A6BF5524CB1C3D0054ADFF /* CopyFiles */,
2114A53FB23FDBBFB2C0A4D1 /* [CP] Embed Pods Frameworks */,
3C492C1B82E7C01036C8C956 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
Expand Down Expand Up @@ -314,7 +314,7 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
2114A53FB23FDBBFB2C0A4D1 /* [CP] Embed Pods Frameworks */ = {
3C492C1B82E7C01036C8C956 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand All @@ -334,7 +334,7 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
FDB3870A5F628D73748E5225 /* [CP] Check Pods Manifest.lock */ = {
7C8C6C314F349CEDD997FF26 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
Expand Down Expand Up @@ -486,7 +486,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SAMPLE_CODE_DISAMBIGUATOR = "$(DEVELOPMENT_TEAM)";
Expand Down Expand Up @@ -542,7 +542,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = NO;
SAMPLE_CODE_DISAMBIGUATOR = "$(DEVELOPMENT_TEAM)";
SDKROOT = iphoneos;
Expand All @@ -554,7 +554,7 @@
};
C16F40B02094F07C009CE87C /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D0BA0AF20D590A047F38D5AE /* Pods-Example.debug.xcconfig */;
baseConfigurationReference = 68331A81F431D3EB50C6D085 /* Pods-Example.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
Expand All @@ -571,7 +571,7 @@
);
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
INFOPLIST_FILE = Example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -587,7 +587,7 @@
};
C16F40B12094F07C009CE87C /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 4FD82F87B0169B182DE08E4B /* Pods-Example.release.xcconfig */;
baseConfigurationReference = 5F298C7CAAC76F0FE28E79E3 /* Pods-Example.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
Expand All @@ -604,7 +604,7 @@
);
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
INFOPLIST_FILE = Example/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
5 changes: 1 addition & 4 deletions Example/Example/CollectDataViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,12 @@ import Static
import StripeTerminal

class CollectDataViewController: EventDisplayingViewController {
override var cancelLogMethod: LogEvent.Method {
return .cancelCollectData
}

private let collectDataConfig: CollectDataConfiguration

init(collectDataConfiguration: CollectDataConfiguration) {
self.collectDataConfig = collectDataConfiguration
super.init()
self.currentCancelLogMethod = .cancelCollectData
}

required init?(coder aDecoder: NSCoder) {
Expand Down
Loading

0 comments on commit b22040e

Please sign in to comment.