basic networking questions

I have a few apps out that I have built with Corona and I am now looking to try and improve them with some substantial updates. From what I have gathered most of the updates I would really like to do would involve figuring out how networking works.

things I would like to include in my apps would be non-consumable IAP and multiplayer and I have read that both of these require networking.

One thing I noticed is that with non-consumable IAP I need to be able to store purchase info so that at a later point the player can restore download data if need be.

On the side of multiplayer I have come across PhotonCloud with corona that seems to be a good resolution to the multiplayer challenge.

My question is this, does anyone have any good beginner tips for finding resources to set up minimal data storage with my apps… and anyone with experience with photoncloud and setting up multiplayer, is that a good path to go and could I set up data storage with photoncloud

You can handle all your IAP needs without networking since restore data is stored by the related company. You can use Google IAP for Google Play, Amazon IAP for Amazon and the Store API for Apple. You can also find a sample app for that in Corona Simulator.

https://docs.coronalabs.com/api/library/store/index.html

https://docs.coronalabs.com/plugin/amazon-iap-v2/index.html

https://docs.coronalabs.com/plugin/google-iap-v3/index.html

“Networking” is a very broad and loose term. For a Corona built app, this can run the gamut of writing low-level socket IO code to using libraries and plugins that do all the work for you or somewhere in between.

For IAP, you won’t need to worry one bit about networking more than knowing that your app owner’s have to have the network on to make purchases. IAP has its own complexities (setting up the iTunes Connect/Google Developer Portal entries), understanding how transactions work back in your app but “Networking” isn’t one of those worries.

For Multi-Player depending on how you implement it, the plugins will likely handle all the networking for you. You just call the plugin’s various APIs and have functions to handle the results they send back to you.

@bgmadclown pointed you to a bunch of IAP resources.  But on the multi-player side, the choices become a bit more narrowed depending on what you want to do with multi-player.  

Photon is a great service for multi-player games where your app needs to know the state of the game constantly. For instance, if your trying to do a multiplayer role-playing game where multiple characters are moving around the same map, you would want to use Photon because their specialty is their fast reporting of game information. But if you’re making a game like “Words with Friends” that’s turn based between two players that they take their turns at their leisure, then you could get away with GameKit, GPGS and Amazon GameCircle (though Apple GameKit players could not play with Google Play Games Service players). But that’s were a plugin like PlayFab comes in. It can manage your multplayer game needs in a cross-platform way.  But with any of these, you’re not going to be writing your own network code, just calling the API’s of the plugins.

Rob

Thanks for the resources.

I have a question about the store.restore() function https://docs.coronalabs.com/api/library/store/restore.html

I had non-consumable content to download as an IAP, but ended up removing it because I could not figure out how to restore it. Basically what I did was have a separate button thats function was restore. All the button did was call store.restore() when pushed, but it did absolutely nothing and would get rejected by apple saying I needed a way for users to restore non-consumable IAP when I tried to submit it.

When reading the store.restore() api reference, it doesn’t really explain what you should put but it does hint that in the store transaction listener the state will be “restored”. So I get that I should have some code there, but really kind of clueless as to what

could someone give an example code of what should be expected in the store transaction listener under transaction.state == “restored”

First, Apple requires that the store.restore() function be called by a user action (i.e. a “Restore” button). Consumable purchases are never restored. If there are non-consumable items that have been purchased, calling store.restore() should trigger a “restored” event in the transaction listener, one for each purchased non-consumable item. You can handle them just like a purchase. That is unlock whatever needs unlocked, set whatever settings get set.

On Android, Google kinda hints they want store.restore() called when the app starts up. The main reason for the difference is Apple is going to prompt for a login each time store.restore() is called, Google does not. Google also does  not have a “restored” transaction type. Restored purchases come in as purchases, just with an older date. Since this matters when someone deletes and app and re-installs it, a re-installed app would be locked and processing restore’s and purchases would accomplish the same thing.

Rob

I’m mainly focused on iOS right now.

so calling store.restore() says the following fields of the transaction object will provide context about the original purchase.

  • originalReceipt — a unique receipt from the original purchase attempt, returned as a hexadecimal string.
  • originalIdentifier — a unique transaction identifier (string) returned from the original purchase attempt.
  • originalDate — the date when the original transaction occurred.

if I were to have a button that called store.restore() it would then go to my transaction listener function and deal with what is under the transaction.state == “restored” section.

I’m still a little lost as to what exactly Im supposed to put under the

if transaction.state == "restored" then RESTORE ANY NON-CONSUMABLE ITEMS PREVIOUSLY PURCHASED end

You can use a native.showAlert() to inform the user that his/her items are restored from previous purchases and make those items available in your code like unlocking the full game.

You do what you did when they originally purchased the item. Lets say for instance, Your IAP lets them turn off ads or somehow sets a flag that they’ve paid for the app. You might have a variable like:

local isPaid = false

Then you have a button somewhere that lets them purchase something to unlock/pay for the app. In your transactionListener you probably have something like:

if transaction.state == "purchased" then if transaction.productIdentifier == "com.yourreversedomain.yourapp.unlockApp" then -- or whatever you named the purchase item       isPaid = true     -- code to save the setting native.showAlert("Your App Name", "Thank you for your support!", { "Ok" } ) end -- you can have multiple items... but will only do a basic unlock here. end

Then else where you might have:

if not isPaid then      someAdProvider.show() end

This basic setup lets you buy something. When the sale is confirmed the flag showing the app is paid for is set and then anything you do for free apps is wrapped in an if statement like above. When the flag is true, the code in the if executes.

Now someone deletes their app. You’ve lost track of that saved setting and no longer know if isPaid is true or false so you have to assume it’s false. This is where store.restore() comes into play. Now the user knows they have previous unlocked the app. They press the restore button which calls store.restore() and you get your transaction listener called:

if transaction.state == "restored" then if transaction.productIdentifier == "com.yourreversedomain.yourapp.unlockApp" then -- or whatever you named the purchase item isPaid = true -- code to save the setting native.showAlert("Your App Name", "You're purchases have been restored!", { "Ok" } ) end -- you can have multiple items... but will only do a basic unlock here. end

If you don’t want to have an alert show for each of them and just wanted to silently make them work you could combine it into a single if test:

if transaction.state == "purchased" or transaction.state == "restored" then ...

But most people may want to do something a little different with purchases than they do with restores.

Rob

You can handle all your IAP needs without networking since restore data is stored by the related company. You can use Google IAP for Google Play, Amazon IAP for Amazon and the Store API for Apple. You can also find a sample app for that in Corona Simulator.

https://docs.coronalabs.com/api/library/store/index.html

https://docs.coronalabs.com/plugin/amazon-iap-v2/index.html

https://docs.coronalabs.com/plugin/google-iap-v3/index.html

“Networking” is a very broad and loose term. For a Corona built app, this can run the gamut of writing low-level socket IO code to using libraries and plugins that do all the work for you or somewhere in between.

For IAP, you won’t need to worry one bit about networking more than knowing that your app owner’s have to have the network on to make purchases. IAP has its own complexities (setting up the iTunes Connect/Google Developer Portal entries), understanding how transactions work back in your app but “Networking” isn’t one of those worries.

For Multi-Player depending on how you implement it, the plugins will likely handle all the networking for you. You just call the plugin’s various APIs and have functions to handle the results they send back to you.

@bgmadclown pointed you to a bunch of IAP resources.  But on the multi-player side, the choices become a bit more narrowed depending on what you want to do with multi-player.  

Photon is a great service for multi-player games where your app needs to know the state of the game constantly. For instance, if your trying to do a multiplayer role-playing game where multiple characters are moving around the same map, you would want to use Photon because their specialty is their fast reporting of game information. But if you’re making a game like “Words with Friends” that’s turn based between two players that they take their turns at their leisure, then you could get away with GameKit, GPGS and Amazon GameCircle (though Apple GameKit players could not play with Google Play Games Service players). But that’s were a plugin like PlayFab comes in. It can manage your multplayer game needs in a cross-platform way.  But with any of these, you’re not going to be writing your own network code, just calling the API’s of the plugins.

Rob

Thanks for the resources.

I have a question about the store.restore() function https://docs.coronalabs.com/api/library/store/restore.html

I had non-consumable content to download as an IAP, but ended up removing it because I could not figure out how to restore it. Basically what I did was have a separate button thats function was restore. All the button did was call store.restore() when pushed, but it did absolutely nothing and would get rejected by apple saying I needed a way for users to restore non-consumable IAP when I tried to submit it.

When reading the store.restore() api reference, it doesn’t really explain what you should put but it does hint that in the store transaction listener the state will be “restored”. So I get that I should have some code there, but really kind of clueless as to what

could someone give an example code of what should be expected in the store transaction listener under transaction.state == “restored”

First, Apple requires that the store.restore() function be called by a user action (i.e. a “Restore” button). Consumable purchases are never restored. If there are non-consumable items that have been purchased, calling store.restore() should trigger a “restored” event in the transaction listener, one for each purchased non-consumable item. You can handle them just like a purchase. That is unlock whatever needs unlocked, set whatever settings get set.

On Android, Google kinda hints they want store.restore() called when the app starts up. The main reason for the difference is Apple is going to prompt for a login each time store.restore() is called, Google does not. Google also does  not have a “restored” transaction type. Restored purchases come in as purchases, just with an older date. Since this matters when someone deletes and app and re-installs it, a re-installed app would be locked and processing restore’s and purchases would accomplish the same thing.

Rob

I’m mainly focused on iOS right now.

so calling store.restore() says the following fields of the transaction object will provide context about the original purchase.

  • originalReceipt — a unique receipt from the original purchase attempt, returned as a hexadecimal string.
  • originalIdentifier — a unique transaction identifier (string) returned from the original purchase attempt.
  • originalDate — the date when the original transaction occurred.

if I were to have a button that called store.restore() it would then go to my transaction listener function and deal with what is under the transaction.state == “restored” section.

I’m still a little lost as to what exactly Im supposed to put under the

if transaction.state == "restored" then RESTORE ANY NON-CONSUMABLE ITEMS PREVIOUSLY PURCHASED end

You can use a native.showAlert() to inform the user that his/her items are restored from previous purchases and make those items available in your code like unlocking the full game.

You do what you did when they originally purchased the item. Lets say for instance, Your IAP lets them turn off ads or somehow sets a flag that they’ve paid for the app. You might have a variable like:

local isPaid = false

Then you have a button somewhere that lets them purchase something to unlock/pay for the app. In your transactionListener you probably have something like:

if transaction.state == "purchased" then if transaction.productIdentifier == "com.yourreversedomain.yourapp.unlockApp" then -- or whatever you named the purchase item       isPaid = true     -- code to save the setting native.showAlert("Your App Name", "Thank you for your support!", { "Ok" } ) end -- you can have multiple items... but will only do a basic unlock here. end

Then else where you might have:

if not isPaid then      someAdProvider.show() end

This basic setup lets you buy something. When the sale is confirmed the flag showing the app is paid for is set and then anything you do for free apps is wrapped in an if statement like above. When the flag is true, the code in the if executes.

Now someone deletes their app. You’ve lost track of that saved setting and no longer know if isPaid is true or false so you have to assume it’s false. This is where store.restore() comes into play. Now the user knows they have previous unlocked the app. They press the restore button which calls store.restore() and you get your transaction listener called:

if transaction.state == "restored" then if transaction.productIdentifier == "com.yourreversedomain.yourapp.unlockApp" then -- or whatever you named the purchase item isPaid = true -- code to save the setting native.showAlert("Your App Name", "You're purchases have been restored!", { "Ok" } ) end -- you can have multiple items... but will only do a basic unlock here. end

If you don’t want to have an alert show for each of them and just wanted to silently make them work you could combine it into a single if test:

if transaction.state == "purchased" or transaction.state == "restored" then ...

But most people may want to do something a little different with purchases than they do with restores.

Rob