New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[in_app_purchase_storekit] migrate main plugin class to swift in preperation to storekit 2 #6561
Conversation
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/in_app_purchase_storekit.h
Show resolved
Hide resolved
@@ -238,7 +238,7 @@ abstract class InAppPurchaseAPI { | |||
SKProductsResponseMessage startProductRequest( | |||
List<String> productIdentifiers); | |||
|
|||
void finishTransaction(Map<String, String?> finishMap); | |||
void finishTransaction(Map<String, Object?> finishMap); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though the intended type here should be a nullable String, when pigeon generates obj C code, it is generated as type NSString. NSString is nullable in objective c, but when Xcode generates the corresponding swift method signature, it converts into a String, not a String?. NSString also cannot be annoted with _Nullable as it is a generic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
im confused. why is NSString generic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^ this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, its not generic, but you can't specify a type inside a NSDictionary to be nullable. (i dont think)
Specifically here -
packages/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/messages.g.h
Line 268 in 74de10a
- (void)finishTransactionFinishMap:(NSDictionary<NSString *, id> *)finishMap |
What I really want is for this line in swift
packages/packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Line 227 in 74de10a
_ finishMap: [String: Any], error: AutoreleasingUnsafeMutablePointer<FlutterError?> |
To be
finishMap: [String: String?]
. But the automatic conversion turns all NSStrings as String
and not String?
. And because I can't specify the NSString as extra nullable, I have to make it Object?
(in pigeon) so it gets generated into id
in objc, which then will turn into Any
, and thus allow for nullabilityNot sure if that makes sense lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Any
to represent an optional can be error-prone.
Why do you want [String:String?]
? Is there any issue with using [String:String]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how pendingTransactions
is related to the dictionary type. Can you explain how using [String:String]
type would fail to work here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea I meant the comments
Im not understanding the question i think? finishMap should be [String:String?]
because finishMap["transactionIdentifier"]
should be allowed to be null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's just [String:String]
then finishMap["transactionIdentifier"]
wouldn't be allowed to be null, right?
But if finishMap["transactionIdentifier"]
is null and a transaction in pendingTransactions also has a null transactionIdentifier then that would also be a valid transaction. If we had [String:String]
then we couldn't check that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line 218 in 871a24b
Map<String, String?> toFinishMap() => <String, String?>{ |
You can see on the dart side that the finishMap arg it gets called with has [String:String?]
as well - I genuinely do not think it would be correct to make it [String:String]
. Once this gets converted to using Swift pigeon, I can change it from String:Any
to String:String?
, so this should be temporary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
finishMap should be [String:String?] because finishMap["transactionIdentifier"] should be allowed to be null.
If it's just [String:String] then finishMap["transactionIdentifier"] wouldn't be allowed to be null, right?
Not really. dict[key]
always returns optional. If type of finishMap
is [String:String]
, then the type of finishMap["transactionIdentifier"]
would be String?
.
If you use [String:String?]
as the type, then finishMap["transactionIdentifier"]
would be String??
(double optional).
@@ -144,28 +144,6 @@ - (instancetype)initWithMap:(NSDictionary *)map { | |||
|
|||
@end | |||
|
|||
@interface InAppPurchasePluginStub () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This plugin stub needed to be converted to swift as you cannot subclass a swift class in objective C.
Could you run formatter first so it's easier for review? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I briefly looked at the code and did not look into the details. I have to stop early as it's getting long, and there are enough feedback already.
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
|
||
public func handleTransactionsRemoved(_ transactions: [SKPaymentTransaction]) { | ||
var maps: [[AnyHashable: Any]] = [] | ||
for transaction in transactions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here.
return value is NSNull ? nil : value | ||
} | ||
|
||
func getRefreshReceiptRequest(properties: [String: Any]?) -> SKReceiptRefreshRequest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are these helpers only used inside this file? should use private
if that's the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these need to be not private so they can be overriden for testing purposes
Like here:
packages/packages/in_app_purchase/in_app_purchase_storekit/example/ios/RunnerTests/SwiftStubs.swift
Line 11 in 74de10a
override func getProductRequest(withIdentifiers productIdentifiers: Set<String>) |
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/in_app_purchase_storekit.h
Show resolved
Hide resolved
// | ||
|
||
#import "Stubs.h" | ||
#import "Stubs.m" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is it importing the .m file?
@@ -238,7 +238,7 @@ abstract class InAppPurchaseAPI { | |||
SKProductsResponseMessage startProductRequest( | |||
List<String> productIdentifiers); | |||
|
|||
void finishTransaction(Map<String, String?> finishMap); | |||
void finishTransaction(Map<String, Object?> finishMap); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
im confused. why is NSString generic?
I believe the Line 770 in 26bd37b
From the original commit of the project: |
@@ -773,7 +773,6 @@ | |||
MARKETING_VERSION = 1.0; | |||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; | |||
MTL_FAST_MATH = YES; | |||
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/in_app_purchase_storekit/in_app_purchase_storekit.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/integration_test/integration_test.modulemap\" -Xcc -fmodule-map-file=\"${PODS_ROOT}/Headers/Public/shared_preferences_macos/shared_preferences_macos.modulemap\""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two more of these I believe, one for each configuration.
is it ready for another review? |
@hellohuanlin Yeah, please take a look when you can! |
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/in_app_purchase_storekit.h
Outdated
Show resolved
Hide resolved
@@ -1,7 +1,7 @@ | |||
// Copyright 2013 The Flutter Authors. All rights reserved. | |||
// Use of this source code is governed by a BSD-style license that can be | |||
// found in the LICENSE file. | |||
// Autogenerated from Pigeon (v16.0.4), do not edit directly. | |||
// Autogenerated from Pigeon (v16.0.5), do not edit directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this bump required for this pr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, it just gets regenerated. is it worth going down a version to avoid these comment changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to regenerate. just don't check-in the changes that's not related to this PR.
@@ -238,7 +238,7 @@ abstract class InAppPurchaseAPI { | |||
SKProductsResponseMessage startProductRequest( | |||
List<String> productIdentifiers); | |||
|
|||
void finishTransaction(Map<String, String?> finishMap); | |||
void finishTransaction(Map<String, Object?> finishMap); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^ this
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
return value is NSNull ? nil : value | ||
} | ||
|
||
func getRefreshReceiptRequest(properties: [String: Any]?) -> SKReceiptRefreshRequest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started the review, but unless im mistaken, it looks like a few previous comments have not been addressed. can you make sure all previous comments are addressed before i continue?
#endif | ||
|
||
public class InAppPurchasePlugin: NSObject, FlutterPlugin, InAppPurchaseAPI { | ||
// Properties |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need this comment
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting very close
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Show resolved
Hide resolved
packages/in_app_purchase/in_app_purchase_storekit/darwin/Classes/InAppPurchasePlugin.swift
Outdated
Show resolved
Hide resolved
@@ -238,7 +238,7 @@ abstract class InAppPurchaseAPI { | |||
SKProductsResponseMessage startProductRequest( | |||
List<String> productIdentifiers); | |||
|
|||
void finishTransaction(Map<String, String?> finishMap); | |||
void finishTransaction(Map<String, Object?> finishMap); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Any
to represent an optional can be error-prone.
Why do you want [String:String?]
? Is there any issue with using [String:String]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks for making all the changes! Please make sure to manually test out if the feature still works as expected.
Part of flutter/flutter#119106
This PR migrates the main InAppPurchasePlugin.m class to swift.
Pre-launch Checklist
dart format
.)[shared_preferences]
pubspec.yaml
with an appropriate new version according to the [pub versioning philosophy], or this PR is [exempt from version changes].CHANGELOG.md
to add a description of the change, [following repository CHANGELOG style].///
).