-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[In_app_purchase] getproductlist basic draft #1169
Conversation
| /// | ||
| /// Returns a List of [Product] that each [Product] uniquely matches one valid identifier in [identifiers]. | ||
| /// Any item in the `identifiers` that is not specified in App Store Connect or Google Play Console will be ignored. | ||
| Future<List<Product>> queryProductDetails(List<String> identifiers); |
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.
An alternative could be returning a custom 'Response' class something like ProductResponse which contains the list of the product and some errors if any. Any thoughts on 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.
I like that idea but I don't know what information we would be setting as the response code.
BillingClient returns an error code sometimes, and StoreKit returns a list of invalidProductIdentifiers. How would we combine that in a way that makes sense?
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.
That's also what blocking me to introduce the response class.
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.
Discussed offline, going to add a response with a list of the not found product IDs.
mklim
left a comment
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.
Some API feedback but the underlying code is solid.
I also think now would be a good time to update the example app to query the products and list them. Proof of concept here.
| subscriptionPeriod: json['subscriptionPeriod'] as String, | ||
| title: json['title'] as String, | ||
| type: const SkuTypeConverter().fromJson(json['type'] as String), | ||
| type: _$enumDecode(_$SkuTypeEnumMap, json['type']), |
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.
For some reason this generated with extra enum boilerplate and it shouldn't have.
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.
oh yeah I didn't know why this piece of code got changed, I'll discuss with you offline.
packages/in_app_purchase/lib/src/in_app_purchase_connection/product.dart
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/lib/src/in_app_purchase_connection/product.dart
Outdated
Show resolved
Hide resolved
packages/in_app_purchase/lib/src/in_app_purchase_connection/product.dart
Outdated
Show resolved
Hide resolved
| /// | ||
| /// Returns a List of [Product] that each [Product] uniquely matches one valid identifier in [identifiers]. | ||
| /// Any item in the `identifiers` that is not specified in App Store Connect or Google Play Console will be ignored. | ||
| Future<List<Product>> queryProductDetails(List<String> identifiers); |
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 like that idea but I don't know what information we would be setting as the response code.
BillingClient returns an error code sometimes, and StoreKit returns a list of invalidProductIdentifiers. How would we combine that in a way that makes sense?
packages/in_app_purchase/lib/src/in_app_purchase_connection/in_app_purchase_connection.dart
Outdated
Show resolved
Hide resolved
|
@mklim Updated with example app. Please take another look. |
| 'gas', | ||
| 'premium', | ||
| 'upgrade', | ||
| 'somethingNotValid' |
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.
Ideally the example app should just be demoing the right way to use the API. I don't think it's worth deliberately checking for invalid product IDs here. All we're asking people to set up in the README so far is consumable, upgrade, and subscription.
| } | ||
|
|
||
| /// The response returned by [InAppPurchaseConnection.queryProductDetails] | ||
| class QueryProductDetailsResponse { |
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.
nit: I think it would be a little clearer and more concise to name this ProductDetailsResponse. The "Query" part is already implied by "Response" (it's a response to a query).
| QueryProductDetailsResponse( | ||
| {@required this.productDetails, @required this.notFoundIDs}); | ||
|
|
||
| ///Each [ProductDetails] uniquely matches one valid identifier in [identifiers] of [InAppPurchaseConnection.queryProductDetails]. |
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.
nit: Extra whitespace before each sentence in the dartdoc here and below.
|
|
||
| ///The list of identifiers that are in the `identifiers` of [InAppPurchaseConnection.queryProductDetails] but failed to be fetched. | ||
| /// | ||
| ///These are the identifiers not matching the `productIdentifer` or `sku` in any product on the App Store Connect or Google Play Console. |
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'd also avoid mentioning the underlying platforms here. "failed to be fetched" is about as specific as we can safely get at this layer without going into a bunch of platform specific details I think. For example I know in the App Store case invalidIdentifiers will be full of "valid" products in a lot of cases where the IDs do match whatever is in App Store connect and the problem is really in some other configuration in either the app or its store listing.
Maybe we could broadly point the users to look into the underlying platforms if they're seeing this failing? Like, "There's multiple platform specific reasons that product information could fail to be fetched, ranging from products not being correctly configured in the storefront to the queried IDs not existing." That's unfortunately not very helpful on its own, but I think that's really all the information we have at this level.
|
|
||
| /// Query the product detail list. | ||
| /// | ||
| /// This method only returns [QueryProductDetailsResponse]. |
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.
FYI I don't think this or GooglePlayConnection really need dart doc, since we're not exposing either of them as public API classes and they're overriding the documented public interface. You also don't need to delete documentation you've already written though.
| Future<QueryProductDetailsResponse> queryProductDetails( | ||
| Set<String> identifiers) async { | ||
| SkuDetailsResponseWrapper inappResponse = | ||
| await _billingClient.querySkuDetails( |
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.
nit: It would be a little faster if these two queries happened in parallel and we blocked on them both completing in general, instead of blocking on both of them sequentially.
I think you can use Future.wait to block on multiple futures resolving.
| skuType: SkuType.inapp, skusList: identifiers.toList()); | ||
| SkuDetailsResponseWrapper subResponse = await _billingClient | ||
| .querySkuDetails(skuType: SkuType.subs, skusList: identifiers.toList()); | ||
| List<ProductDetails> inappProducts = inappResponse.skuDetailsList |
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.
nit, subjective: instead of writing this conversion twice what about combining these lists first?
Something like:
List<ProductDetails> products = (inappResponse.skuDetailsList + subResponse.skuDetailsList)
.map((SkuDetailsWrapper wrapper) => //etc
| /// Returns true if the payment platform is ready and available. | ||
| Future<bool> isAvailable(); | ||
|
|
||
| /// Query the product details list. |
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.
nit: I don't think we're really querying from a pre-existing list of product details here. It's more like we're querying for product details that match the given set of identifiers.
|
|
||
| /// The class represents the information of a product. | ||
| /// | ||
| /// A list of [ProductDetails] can be obtained from the [QueryProductDetailsResponse]. |
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.
nit, subjective: I think it would be more helpful to link to Connection.queryProductDetails here than the response data class specifically.
|
@mklim Updated with suggested reviews. |
mklim
left a comment
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.
Contains the basic draft of the combined api to get product details. Add an example app to demonstrate the usage.
This reverts commit 35da9be.
Contains the basic draft of the combined api to get product details. Add an example app to demonstrate the usage.
Contains the basic draft of the combined api to get product details. Add an example app to demonstrate the usage.

This is a very basic first draft for combining android and iOS get product list.
Would like this to be solid before working into more details.