Skip to content

Commit fe1bfae

Browse files
authored
Merge branch 'main' into main
2 parents 137c5e3 + 3c7859f commit fe1bfae

File tree

27 files changed

+321
-169
lines changed

27 files changed

+321
-169
lines changed

.ci/flutter_master.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
d8baa77b38461e7061e06e72c6bf50d64d302b8c
1+
7e30df2225f65141e0227e424986311b79d39505

packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.4.2
2+
3+
* Add [jwsRepresentation](https://developer.apple.com/documentation/storekit/verificationresult/jwsrepresentation-21vgo) to `SK2PurchaseDetails` as `serverVerificationData` for secure server-side purchase verification. Use this JSON Web Signature (JWS) value to perform your own JWS verification on your server.
4+
* Add [jsonRepresentation](https://developer.apple.com/documentation/storekit/transaction/jsonrepresentation) to `SK2PurchaseDetails` as `localVerificationData` for local transaction debugging and verification.
5+
16
## 0.4.1
27

38
* Updates minimum supported SDK version to Flutter 3.27/Dart 3.6.

packages/in_app_purchase/in_app_purchase_storekit/darwin/in_app_purchase_storekit/Sources/in_app_purchase_storekit/StoreKit2/InAppPurchasePlugin+StoreKit2.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ extension InAppPurchasePlugin: InAppPurchase2API {
8888
case .success(let verification):
8989
switch verification {
9090
case .verified(let transaction):
91-
self.sendTransactionUpdate(transaction: transaction)
91+
self.sendTransactionUpdate(
92+
transaction: transaction, receipt: verification.jwsRepresentation)
9293
completion(.success(result.convertToPigeon()))
9394
case .unverified(_, let error):
9495
completion(.failure(error))
@@ -284,7 +285,8 @@ extension InAppPurchasePlugin: InAppPurchase2API {
284285
for await verificationResult in Transaction.updates {
285286
switch verificationResult {
286287
case .verified(let transaction):
287-
self?.sendTransactionUpdate(transaction: transaction)
288+
self?.sendTransactionUpdate(
289+
transaction: transaction, receipt: verificationResult.jwsRepresentation)
288290
case .unverified:
289291
break
290292
}

packages/in_app_purchase/in_app_purchase_storekit/lib/src/store_kit_2_wrappers/sk2_transaction_wrapper.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,10 @@ extension on SK2TransactionMessage {
121121
// receipt isn’t necessary with SK2 as a Transaction can only be returned
122122
// from validated purchases.
123123
verificationData: PurchaseVerificationData(
124-
localVerificationData: '', serverVerificationData: '', source: ''),
124+
localVerificationData: jsonRepresentation ?? '',
125+
// receiptData is the JWS representation of the transaction
126+
serverVerificationData: receiptData ?? '',
127+
source: kIAPSource),
125128
transactionDate: purchaseDate,
126129
// Note that with SK2, any transactions that *can* be returned will
127130
// require to be finished, and are already purchased.

packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: in_app_purchase_storekit
22
description: An implementation for the iOS and macOS platforms of the Flutter `in_app_purchase` plugin. This uses the StoreKit Framework.
33
repository: https://github.com/flutter/packages/tree/main/packages/in_app_purchase/in_app_purchase_storekit
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
5-
version: 0.4.1
5+
version: 0.4.2
66

77
environment:
88
sdk: ^3.6.0

packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,5 +442,7 @@ SK2TransactionMessage createPendingTransaction(String id, {int quantity = 1}) {
442442
originalId: 2,
443443
productId: id,
444444
purchaseDate: 'purchaseDate',
445-
appAccountToken: 'appAccountToken');
445+
appAccountToken: 'appAccountToken',
446+
receiptData: 'receiptData',
447+
jsonRepresentation: 'jsonRepresentation');
446448
}

packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_2_platform_test.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,38 @@ void main() {
154154
throwsA(isInstanceOf<AssertionError>()));
155155
});
156156

157+
test(
158+
'buying consumable, should get PurchaseVerificationData with serverVerificationData and localVerificationData',
159+
() async {
160+
final List<PurchaseDetails> details = <PurchaseDetails>[];
161+
final Completer<List<PurchaseDetails>> completer =
162+
Completer<List<PurchaseDetails>>();
163+
final Stream<List<PurchaseDetails>> stream =
164+
iapStoreKitPlatform.purchaseStream;
165+
166+
late final StreamSubscription<List<PurchaseDetails>> subscription;
167+
subscription = stream.listen((List<PurchaseDetails> purchaseDetailsList) {
168+
details.addAll(purchaseDetailsList);
169+
if (purchaseDetailsList.first.status == PurchaseStatus.purchased) {
170+
completer.complete(details);
171+
subscription.cancel();
172+
}
173+
});
174+
final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam(
175+
productDetails:
176+
AppStoreProduct2Details.fromSK2Product(dummyProductWrapper),
177+
applicationUserName: 'appName');
178+
await iapStoreKitPlatform.buyConsumable(purchaseParam: purchaseParam);
179+
180+
final List<PurchaseDetails> result = await completer.future;
181+
expect(result.length, 1);
182+
expect(result.first.productID, dummyProductWrapper.id);
183+
expect(
184+
result.first.verificationData.serverVerificationData, 'receiptData');
185+
expect(result.first.verificationData.localVerificationData,
186+
'jsonRepresentation');
187+
});
188+
157189
test('should process Sk2PurchaseParam with winBackOfferId only', () async {
158190
final Sk2PurchaseParam purchaseParam = Sk2PurchaseParam(
159191
productDetails:

packages/pigeon/example/app/ios/Runner/AppDelegate.swift

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,26 @@ func sendEvents(_ eventListener: EventListener) {
100100
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
101101
) -> Bool {
102102
GeneratedPluginRegistrant.register(with: self)
103+
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
104+
}
105+
}
106+
107+
// TODO(stuartmorgan): Once 3.33+ reaches stable, remove this subclass and move the setup to
108+
// AppDelegate.register(...). This approach is only used because this example needs to support
109+
// both stable and master, and 3.32 doesn't have FlutterPluginRegistrant, while 3.33+ can't use
110+
// the older application(didFinishLaunchingWithOptions) approach.
111+
@objc class ExampleViewController: FlutterViewController {
112+
override func awakeFromNib() {
113+
super.awakeFromNib()
103114

104-
let controller = window?.rootViewController as! FlutterViewController
105115
let api = PigeonApiImplementation()
106-
ExampleHostApiSetup.setUp(binaryMessenger: controller.binaryMessenger, api: api)
116+
ExampleHostApiSetup.setUp(binaryMessenger: binaryMessenger, api: api)
117+
let controller = self
107118
// #docregion swift-init-event
108119
let eventListener = EventListener()
109120
StreamEventsStreamHandler.register(
110121
with: controller.binaryMessenger, streamHandler: eventListener)
111122
// #enddocregion swift-init-event
112123
sendEvents(eventListener)
113-
114-
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
115-
116124
}
117125
}

packages/pigeon/example/app/ios/Runner/Base.lproj/Main.storyboard

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
1-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
3+
<device id="retina6_12" orientation="portrait" appearance="light"/>
34
<dependencies>
45
<deployment identifier="iOS"/>
5-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
6+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
7+
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
68
</dependencies>
79
<scenes>
8-
<!--Flutter View Controller-->
10+
<!--Example View Controller-->
911
<scene sceneID="tne-QT-ifu">
1012
<objects>
11-
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
13+
<viewController id="BYZ-38-t0r" customClass="ExampleViewController" customModule="Runner" customModuleProvider="target" sceneMemberID="viewController">
1214
<layoutGuides>
1315
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
1416
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
1517
</layoutGuides>
1618
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
17-
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
19+
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
1820
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
19-
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
21+
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
2022
</view>
2123
</viewController>
2224
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>

packages/quick_actions/quick_actions_ios/example/ios/RunnerUITests/RunnerUITests.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ class RunnerUITests: XCTestCase {
3636
exampleApp = nil
3737
}
3838

39-
func testQuickActionWithFreshStart() {
39+
func testQuickActionWithFreshStart() throws {
40+
// See https://github.com/flutter/flutter/issues/169928
41+
throw XCTSkip("Temporarily disabled")
42+
4043
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
4144
let quickActionsAppIcon = springboard.icons["quick_actions_example"]
4245

@@ -53,7 +56,10 @@ class RunnerUITests: XCTestCase {
5356
XCTAssert(actionTwoConfirmation.exists)
5457
}
5558

56-
func testQuickActionWhenAppIsInBackground() {
59+
func testQuickActionWhenAppIsInBackground() throws {
60+
// See https://github.com/flutter/flutter/issues/169928
61+
throw XCTSkip("Temporarily disabled")
62+
5763
exampleApp.launch()
5864

5965
let actionsReady = exampleApp.otherElements["actions ready"]

0 commit comments

Comments
 (0)