Browse Source

IAP tweaks.

Mark Sibly 7 years ago
parent
commit
d2acfd573e

+ 55 - 26
modules/iap/bananas/iaptest.monkey2

@@ -6,6 +6,7 @@ IMPORTANT!
 This wont work 'as is'! You'll need to set up a bunch of stuff on GooglePlay/iTunes Connect developer portal such as app/products etc.
 
 #end
+
 Namespace myapp
 
 #Import "<iap>"
@@ -28,12 +29,16 @@ Class MyWindow Extends Window
 
 	Field _listView:ListView
 
+	Field _openStoreItem:ListView.Item
+	
+	Field _restorePurchasesItem:ListView.Item
+	
 	Field _iap:IAPStore
 	
 	Method New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )
 
 		Super.New( title,width,height,flags )
-
+		
 		Layout="stretch"
 		
 		'Create our IAP products.
@@ -43,7 +48,7 @@ Class MyWindow Extends Window
 			New Product( "bullet_boost",ProductType.Consumable ),
 			New Product( "ship_upgrade",ProductType.NonConsumable ) )
 		
-		'Load purchases we've alreday bought.
+		'Load purchases we've already bought.
 		'
 		LoadPurchases()
 
@@ -55,17 +60,23 @@ Class MyWindow Extends Window
 		
 		_listView.ItemClicked=Lambda( item:ListView.Item )
 		
-			If _iap.Busy Return
+			If Not _iap Or _iap.Busy Return
 			
-			Local index:= _listView.IndexOfItem( item )
+			If item=_restorePurchasesItem
+
+				_iap.GetOwnedProducts()
+
+				Return
+			Endif
 			
-			If index=_products.Length
+			If item=_openStoreItem
 				
-				_iap.GetOwnedProducts()
+				OpenStore()
 				
 				Return
-			
 			Endif
+
+			Local index:= _listView.IndexOfItem( item )
 			
 			Local product:=_products[ index ]
 			
@@ -80,14 +91,37 @@ Class MyWindow Extends Window
 		
 		ContentView=_listView
 		
+		OpenStore()
+	End
+	
+	Method MakePurchase( product:Product )
+		
+		Select product.Type
+		Case ProductType.Consumable
+			_purchases.SetNumber( product.Identifier,_purchases.GetNumber( product.Identifier )+1 )
+		Case ProductType.NonConsumable
+			_purchases.SetNumber( product.Identifier,1 )
+		End
+	End
+	
+	Method OpenStore()
+
+		_iap?.CloseStore()
+		_iap=Null
+		
 		'Create IAPStore and various handlers.
 		'
 		_iap=New IAPStore
-		
-		'This isc alled when OpenStore completes.
+
+		GCCollect()
+		GCCollect()
+
+		'This is called when OpenStore completes.
 		'
 		_iap.OpenStoreComplete=Lambda( result:Int,interrupted:Product[],owned:Product[] )
 		
+			Print "OpenStoreComplete result="+result
+		
 			Select result
 			Case 0
 
@@ -104,7 +138,7 @@ Class MyWindow Extends Window
 				'you (as long as you're logged in anyway) so you don't strictly need to save them, but you do on ios so for the sake of 
 				'uniformity we will on android too.
 				'
-				'On Android, you never really need to use GetOwnProducts() because you are given this array of owned products when the store
+				'On Android, you never really need to use GetOwnedProducts() because you are given this array of owned products when the store
 				'opens. So in a sense, android automatically 'restores purchases' whenever you open the store.
 				'
 				'This array is always empty on ios. To restore non-consumables on ios you must call GetOwnedProducts in response to the push
@@ -117,13 +151,13 @@ Class MyWindow Extends Window
 				Next
 				
 				SavePurchases()
-				UpdateListView()
 				
 				_info="OpenStore successful"
 			Default
 				_info="OpenStore error:"+result
 			End
-		
+
+			UpdateListView()
 		End
 		
 		'This is called when BuyProduct completes.
@@ -165,21 +199,11 @@ Class MyWindow Extends Window
 			End
 			
 		End
-		
 
 		_iap.OpenStore( _products )
 		
 		_info="Opening store..."
-	End
-	
-	Method MakePurchase( product:Product )
 		
-		Select product.Type
-		Case ProductType.Consumable
-			_purchases.SetNumber( product.Identifier,_purchases.GetNumber( product.Identifier )+1 )
-		Case ProductType.NonConsumable
-			_purchases.SetNumber( product.Identifier,1 )
-		End
 	End
 	
 	Method LoadPurchases()
@@ -216,7 +240,11 @@ Class MyWindow Extends Window
 
 		_listView.RemoveAllItems()
 		
-		If _iap.Open
+		_restorePurchasesItem=Null
+		
+		_openStoreItem=Null
+		
+		If _iap?.Open
 		
 			For Local product:=Eachin _products
 				
@@ -227,15 +255,16 @@ Class MyWindow Extends Window
 				_listView.AddItem( product.Title+" - "+product.Description+" for the low price of "+product.Price+" ("+_purchases.GetNumber( product.Identifier )+")" )
 			Next
 			
-		Endif
+			_restorePurchasesItem=_listView.AddItem( "[RESTORE PURCHASES]" )
 			
-		_listView.AddItem( "[RESTORE PURCHASES]" )
+		Endif
 		
+		_openStoreItem=_listView.AddItem( "[REOPEN STORE]" )
 	End
 	
 	Method OnRender( canvas:Canvas ) Override
 		
-		App.RequestRender()
+		RequestRender()
 		
 		canvas.DrawText( "Hello World!",Width/2,Height/2,.5,.5 )
 		

+ 43 - 5
modules/iap/iap.monkey2

@@ -49,7 +49,7 @@ Class IAPStore
 	
 	Method OpenStore( products:Product[] )
 		
-		If _state>0 Return
+		If _state<>0 Return
 		
 		_products=products
 
@@ -57,20 +57,36 @@ Class IAPStore
 		
 		App.Idle+=UpdateState
 
-		_iap.OpenStoreAsync( _products )
+		If _iap.OpenStoreAsync( _products ) Return
+		
+		App.Idle-=UpdateState
+		
+		_state=0
+		
+		OpenStoreComplete( -1,Null,Null )
 	End
 	
 	Method BuyProduct( product:Product )
 		
 		If _state<>1 Return
 		
+		Print "_state="+_state
+		
 		_buying=product
 		
 		_state=3
 		
 		App.Idle+=UpdateState
 		
-		_iap.BuyProductAsync( product )
+		If _iap.BuyProductAsync( _buying ) Return
+		
+		App.Idle-=UpdateState
+		
+		_buying=Null
+		
+		_state=1
+		
+		BuyProductComplete( -1,product )
 	End
 	
 	Method GetOwnedProducts()
@@ -81,7 +97,29 @@ Class IAPStore
 		
 		App.Idle+=UpdateState
 		
-		_iap.GetOwnedProductsAsync()
+		If _iap.GetOwnedProductsAsync() Return
+		
+		App.Idle-=UpdateState
+		
+		_state=1
+		
+		GetOwnedProductsComplete( -1,Null )
+	End
+	
+	Method CloseStore()
+		
+		If _state<>1 Return
+		
+		_iap.CloseStore()
+		
+		_iap=Null
+		
+		_state=-1
+	End
+	
+	Function CanMakePayments:Bool()
+		
+		Return IAPStoreRep.CanMakePayments()
 	End
 	
 	Private
@@ -110,7 +148,7 @@ Class IAPStore
 		Case 2	'openstore
 			
 			If result<0 _state=0
-			
+
 			Local interrupted:=New Stack<Product>
 			Local owned:=New Stack<Product>
 			For Local product:=Eachin _products

+ 8 - 0
modules/iap/iap_android.monkey2

@@ -136,6 +136,9 @@ Class IAPStoreRep
 		Return Env.CallBooleanMethod( _instance,_getownedproductsasync,Null )
 	End
 	
+	Method CloseStore:Void()
+	End
+	
 	Method IsRunning:Bool()
 		
 		Return Env.CallBooleanMethod( _instance,_isrunning,Null )
@@ -146,6 +149,11 @@ Class IAPStoreRep
 		Return Env.CallIntMethod( _instance,_getresult,Null )
 	End
 	
+	Function CanMakePayments:Bool()
+		
+		Return True
+	End
+	
 	Private
 	
 	Global _class:jclass

+ 3 - 0
modules/iap/iap_ios.monkey2

@@ -23,9 +23,12 @@ Class BBIAPStore="BBIAPStore"
 	Method BBOpenStoreAsync:Bool( products:BBProduct[] )="OpenStoreAsync"
 	Method BBBuyProductAsync:Bool( product:BBProduct )="BuyProductAsync"
 	Method GetOwnedProductsAsync:Bool()
+	Method CloseStore()
 	
 	Method IsRunning:Bool()
 	Method GetResult:Int()
+		
+	Function CanMakePayments:Bool()
 End
 
 public

+ 3 - 0
modules/iap/native/iap_ios.h

@@ -63,10 +63,13 @@ struct BBIAPStore : public bbObject{
 	bool OpenStoreAsync( bbArray<bbGCVar<BBProduct>> products );
 	bool BuyProductAsync( BBProduct* product );
 	bool GetOwnedProductsAsync();
+	void CloseStore();
 	
 	bool IsRunning();
 	int GetResult();
 	
+	static bool CanMakePayments();
+	
 	BBProduct *FindProduct( bbString id );
 	void OnRequestProductDataResponse( SKProductsRequest *request,SKProductsResponse *response );
 	void OnUpdatedTransactions( SKPaymentQueue *queue,NSArray *transactions );

+ 36 - 10
modules/iap/native/iap_ios.mm

@@ -53,10 +53,6 @@ BBProduct::~BBProduct(){
 
 BBIAPStore::BBIAPStore():_running( false ),_products( 0 ),_result( -1 ){
 
-	_delegate=[[BBIAPStoreDelegate alloc] initWithPeer:this];
-	
-	[[SKPaymentQueue defaultQueue] addTransactionObserver:_delegate];
-	
 	_priceFormatter=[[NSNumberFormatter alloc] init];
 	
 	[_priceFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
@@ -69,6 +65,12 @@ bool BBIAPStore::OpenStoreAsync( bbArray<bbGCVar<BBProduct>> products ){
 
 	if( ![SKPaymentQueue canMakePayments] ) return false;
 	
+	if( !_delegate ){	
+		_delegate=[[BBIAPStoreDelegate alloc] initWithPeer:this];
+	
+		[[SKPaymentQueue defaultQueue] addTransactionObserver:_delegate];
+	}
+	
 	_products=products;
 	
 	id __strong *objs=new id[products.length()];
@@ -124,6 +126,15 @@ bool BBIAPStore::GetOwnedProductsAsync(){
 	return true;
 }
 
+void BBIAPStore::CloseStore(){
+
+	if( !_delegate ) return;
+	
+	[[SKPaymentQueue defaultQueue] removeTransactionObserver:_delegate];
+
+	_delegate=0;
+}
+
 bool BBIAPStore::IsRunning(){
 
 	return _running;
@@ -134,6 +145,11 @@ int BBIAPStore::GetResult(){
 	return _result;
 }
 
+bool BBIAPStore::CanMakePayments(){
+
+	return [SKPaymentQueue canMakePayments];
+}
+
 BBProduct *BBIAPStore::FindProduct( bbString id ){
 
 	for( int i=0;i<_products.length();++i ){
@@ -151,7 +167,7 @@ void BBIAPStore::OnRequestProductDataResponse( SKProductsRequest *request,SKProd
 	//Get product details
 	for( SKProduct *p in response.products ){
 	
-		printf( "product=%p\n",p );fflush( stdout );
+//		printf( "product=%p\n",p );fflush( stdout );
 	
 		BBProduct *prod=FindProduct( p.productIdentifier );
 		if( !prod ) continue;
@@ -175,7 +191,13 @@ void BBIAPStore::OnRequestProductDataResponse( SKProductsRequest *request,SKProd
 		_result=0;
 		break;
 	}
-	
+
+	if( _result==-1 ){	
+		[[SKPaymentQueue defaultQueue] removeTransactionObserver:_delegate];
+
+		_delegate=0;
+	}
+
 	_running=false;
 }
 
@@ -187,7 +209,7 @@ void BBIAPStore::OnUpdatedTransactions( SKPaymentQueue *queue,NSArray *transacti
 	
 		if( transaction.transactionState==SKPaymentTransactionStatePurchased ){
 		
-			printf( "IAP purchased\n" );fflush( stdout );
+//			printf( "IAP purchased\n" );fflush( stdout );
 			
 			_result=0;
 			
@@ -195,7 +217,7 @@ void BBIAPStore::OnUpdatedTransactions( SKPaymentQueue *queue,NSArray *transacti
 			
 		}else if( transaction.transactionState==SKPaymentTransactionStateFailed ){
 		
-			printf( "IAP failed %i\n",transaction.error.code );fflush( stdout );
+//			printf( "IAP failed %i\n",transaction.error.code );fflush( stdout );
 			
 			_result=(transaction.error.code==SKErrorPaymentCancelled) ? 1 : -1;
 			
@@ -203,13 +225,13 @@ void BBIAPStore::OnUpdatedTransactions( SKPaymentQueue *queue,NSArray *transacti
 			
 		}else if( transaction.transactionState==SKPaymentTransactionStateRestored ){
 		
-			printf( "IAP restored\n" );fflush( stdout );
+//			printf( "IAP restored\n" );fflush( stdout );
 			
 			if( BBProduct *p=FindProduct( transaction.payment.productIdentifier ) ) p->owned=true;
 		
 		}else{
 		
-			printf( "IAP ?????\n" );fflush( stdout );
+//			printf( "IAP ?????\n" );fflush( stdout );
 
 			continue;
 		}
@@ -227,6 +249,10 @@ void BBIAPStore::OnRestoreTransactionsFinished( SKPaymentQueue *queue,NSError *e
 
 void BBIAPStore::OnRequestFailed( SKRequest *request,NSError *error ){
 
+	[[SKPaymentQueue defaultQueue] removeTransactionObserver:_delegate];
+
+	_delegate=0;
+
 	_running=false;
 }