Browse Source

Turn addTransactionListener into transaction-updated event

Cheng Zhao 7 years ago
parent
commit
133bef3deb

+ 7 - 3
atom/browser/api/atom_api_in_app_purchase.cc

@@ -62,9 +62,7 @@ void InAppPurchase::BuildPrototype(v8::Isolate* isolate,
   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
       .SetMethod("canMakePayments", &in_app_purchase::CanMakePayments)
       .SetMethod("getReceiptURL", &in_app_purchase::GetReceiptURL)
-      .SetMethod("purchaseProduct", &InAppPurchase::PurchaseProduct)
-      .SetMethod("addTransactionListener",
-                 &in_app_purchase::AddTransactionObserver);
+      .SetMethod("purchaseProduct", &InAppPurchase::PurchaseProduct);
 }
 
 InAppPurchase::InAppPurchase(v8::Isolate* isolate) {
@@ -83,6 +81,12 @@ void InAppPurchase::PurchaseProduct(const std::string& product_id,
   in_app_purchase::PurchaseProduct(product_id, quantity, callback);
 }
 
+void InAppPurchase::OnTransactionUpdated(
+    const in_app_purchase::Payment& payment,
+    const in_app_purchase::Transaction& transaction) {
+  Emit("transaction-updated", payment, transaction);
+}
+
 }  // namespace api
 
 }  // namespace atom

+ 7 - 1
atom/browser/api/atom_api_in_app_purchase.h

@@ -16,7 +16,8 @@ namespace atom {
 
 namespace api {
 
-class InAppPurchase: public mate::EventEmitter<InAppPurchase> {
+class InAppPurchase: public mate::EventEmitter<InAppPurchase>,
+                     public in_app_purchase::TransactionObserver {
  public:
   static mate::Handle<InAppPurchase> Create(v8::Isolate* isolate);
 
@@ -29,6 +30,11 @@ class InAppPurchase: public mate::EventEmitter<InAppPurchase> {
 
   void PurchaseProduct(const std::string& product_id, mate::Arguments* args);
 
+  // TransactionObserver:
+  void OnTransactionUpdated(
+      const in_app_purchase::Payment& payment,
+      const in_app_purchase::Transaction& transaction) override;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(InAppPurchase);
 };

+ 21 - 5
atom/browser/mac/in_app_purchase_observer.h

@@ -8,6 +8,13 @@
 #include <string>
 
 #include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+
+#if defined(__OBJC__)
+@class InAppTransactionObserver;
+#else  // __OBJC__
+class InAppTransactionObserver;
+#endif // __OBJC__
 
 namespace in_app_purchase {
 
@@ -27,14 +34,23 @@ struct Transaction {
   std::string transactionState = "";
 };
 
-// --------------------------- Typedefs ---------------------------
+// --------------------------- Classes ---------------------------
+
+class TransactionObserver {
+ public:
+  TransactionObserver();
+  virtual ~TransactionObserver();
 
-typedef base::RepeatingCallback<void(const Payment, const Transaction)>
-    InAppTransactionCallback;
+  virtual void OnTransactionUpdated(const Payment& payment,
+                                    const Transaction& transaction) = 0;
 
-// --------------------------- Functions ---------------------------
+ private:
+  InAppTransactionObserver* obeserver_;
 
-void AddTransactionObserver(const InAppTransactionCallback& callback);
+  base::WeakPtrFactory<TransactionObserver> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(TransactionObserver);
+};
 
 }  // namespace in_app_purchase
 

+ 21 - 10
atom/browser/mac/in_app_purchase_observer.mm

@@ -15,13 +15,20 @@
 //                             InAppTransactionObserver
 // ============================================================================
 
+namespace {
+
+using InAppTransactionCallback =
+    base::RepeatingCallback<void(const in_app_purchase::Payment&,
+                                 const in_app_purchase::Transaction&)>;
+
+}  // namespace
+
 @interface InAppTransactionObserver : NSObject<SKPaymentTransactionObserver> {
  @private
-  in_app_purchase::InAppTransactionCallback callback_;
+  InAppTransactionCallback callback_;
 }
 
-- (id)initWithCallback:
-    (const in_app_purchase::InAppTransactionCallback&)callback;
+- (id)initWithCallback:(const InAppTransactionCallback&)callback;
 
 @end
 
@@ -33,8 +40,7 @@
  * @param callback - The callback that will be called for each transaction
  * update.
  */
-- (id)initWithCallback:
-    (const in_app_purchase::InAppTransactionCallback&)callback {
+- (id)initWithCallback:(const InAppTransactionCallback&)callback {
   if ((self = [super init])) {
     callback_ = callback;
 
@@ -143,7 +149,8 @@
   if (transaction.transactionState < 5) {
     transactionStruct.transactionState = [[@[
       @"SKPaymentTransactionStatePurchasing",
-      @"SKPaymentTransactionStatePurchased", @"SKPaymentTransactionStateFailed",
+      @"SKPaymentTransactionStatePurchased",
+      @"SKPaymentTransactionStateFailed",
       @"SKPaymentTransactionStateRestored",
       @"SKPaymentTransactionStateDeferred"
     ] objectAtIndex:transaction.transactionState] UTF8String];
@@ -176,10 +183,14 @@
 
 namespace in_app_purchase {
 
-void AddTransactionObserver(const InAppTransactionCallback& callback) {
-  // This is leaked, but we should be fine since we don't have a way to remove
-  // callback and the inAppPurchase module is never unloaded.
-  [[InAppTransactionObserver alloc] initWithCallback:callback];
+TransactionObserver::TransactionObserver() : weak_ptr_factory_(this) {
+  obeserver_ = [[InAppTransactionObserver alloc]
+     initWithCallback:base::Bind(&TransactionObserver::OnTransactionUpdated,
+                                 weak_ptr_factory_.GetWeakPtr())];
+}
+
+TransactionObserver::~TransactionObserver() {
+  [obeserver_ release];
 }
 
 }  // namespace in_app_purchase

+ 24 - 18
docs/api/in-app-purchase.md

@@ -1,29 +1,35 @@
 # inAppPurchase  _macOS_
 
-> In-App Purchase on Mac App Store.
+> In-app purchases on Mac App Store.
 
-Your application should add a listener before to purchase a product. If there are no listener attached to the queue, the payment queue does not synchronize its list of pending transactions with the Apple App Store.
+Process: [Main](../glossary.md#main-process)
+
+## Events
+
+The `inAppPurchase` module emits the following events:
+
+### Event: 'transaction-updated'
+
+Emitted when a transaction has been updated.
+
+Returns:
+
+* `event` Event
+* `payment` Object
+  * `productIdentifier` String
+  * `quantity` Integer
+* `transaction` Object
+  * `transactionIdentifier` String
+  * `transactionDate` String
+  * `originalTransactionIdentifier` String
+  * `transactionState` String - The transaction sate (`"SKPaymentTransactionStatePurchasing"`, `"SKPaymentTransactionStatePurchased"`, `"SKPaymentTransactionStateFailed"`, `"SKPaymentTransactionStateRestored"`, or `"SKPaymentTransactionStateDeferred"`)
+  * `errorCode` Integer
+  * `errorMessage` String
 
 ## Methods
 
 The `inAppPurchase` module has the following methods:
 
-### `inAppPurchase.addTransactionListener(listener)`
-
-* `listener` Function - Called when transactions are updated by the payment queue.
-  * `payment` Object
-    * `productIdentifier` String
-    * `quantity` Integer
-  * `transaction` Object
-    * `transactionIdentifier` String
-    * `transactionDate` String
-    * `originalTransactionIdentifier` String
-    * `transactionState` String - The transaction sate (`"SKPaymentTransactionStatePurchasing"`, `"SKPaymentTransactionStatePurchased"`, `"SKPaymentTransactionStateFailed"`, `"SKPaymentTransactionStateRestored"`, or `"SKPaymentTransactionStateDeferred"`)
-    * `errorCode` Integer
-    * `errorMessage` String
-
-Add a listener to transactions.
-
 ### `inAppPurchase.purchaseProduct(productID, quantity, callback)`
 
 * `productID` String - The id of the product to purchase. (the id of `com.example.app.product1` is `product1`).