Plugins for iOS

Godot provides StoreKit, GameCenter, iCloud services and other plugins. They are using same model of asynchronous calls explained below.

ARKit and Camera access are also provided as plugins.

Latest updates, documentation and source code can be found at Godot iOS plugins repository

Accessing plugin singletons

To access plugin functionality, you first need to check that the plugin is exported and available by calling the Engine.has_singleton() function, which returns a registered singleton.

Here's an example of how to do this in GDScript:

var in_app_store
var game_center

func _ready():
    if Engine.has_singleton("InAppStore"):
        in_app_store = Engine.get_singleton("InAppStore")
        print("iOS IAP plugin is not available on this platform.")

    if Engine.has_singleton("GameCenter"):
        game_center = Engine.get_singleton("GameCenter")
        print("iOS Game Center plugin is not available on this platform.")

Asynchronous methods

When requesting an asynchronous operation, the method will look like this:

Error purchase(Variant params);

The parameter will usually be a Dictionary, with the information necessary to make the request, and the call will have two phases. First, the method will immediately return an Error value. If the Error is not 'OK', the call operation is completed, with an error probably caused locally (no internet connection, API incorrectly configured, etc). If the error value is 'OK', a response event will be produced and added to the 'pending events' queue. Example:

func on_purchase_pressed():
    var result = in_app_store.purchase({ "product_id": "my_product" })
    if result == OK:"busy") # show the "waiting for response" animation

# put this on a 1 second timer or something
func check_events():
    while in_app_store.get_pending_event_count() > 0:
        var event = in_app_store.pop_pending_event()
        if event.type == "purchase":
            if event.result == "ok":

Remember that when a call returns OK, the API will always produce an event through the pending_event interface, even if it's an error, or a network timeout, etc. You should be able to, for example, safely block the interface waiting for a reply from the server. If any of the APIs don't behave this way it should be treated as a bug.

The pending event interface consists of two methods:

  • get_pending_event_count() Returns the number of pending events on the queue.

  • Variant pop_pending_event() Pops the first event from the queue and returns it.

Store Kit

Implemented in Godot iOS InAppStore plugin.

The Store Kit API is accessible through the InAppStore singleton. It is initialized automatically.

The following methods are available and documented below:

   Error purchase(Variant params)
   Error request_product_info(Variant params)
   Error restore_purchases()
   void set_auto_finish_transaction(bool enable)
   void finish_transaction(String product_id)

and the pending events interface:


   int get_pending_event_count()
   Variant pop_pending_event()


Purchases a product ID through the Store Kit API. You have to call finish_transaction(product_id) once you receive a successful response or call set_auto_finish_transaction(true) prior to calling purchase(). These two methods ensure the transaction is completed.


Takes a dictionary as a parameter, with one field, product_id, a string with your product ID. Example:

var result = in_app_store.purchase({ "product_id": "my_product" })

Response event

The response event will be a dictionary with the following fields:

On error:

  "type": "purchase",
  "result": "error",
  "product_id": "the product ID requested",

On success:

  "type": "purchase",
  "result": "ok",
  "product_id": "the product ID requested",


Requests the product info on a list of product IDs.


Takes a dictionary as a parameter, with a single product_ids key to which a string array of product IDs is assigned. Example:

var result = in_app_store.request_product_info({ "product_ids": ["my_product1", "my_product2"] })

Response event

The response event will be a dictionary with the following fields:

  "type": "product_info",
  "result": "ok",
  "invalid_ids": [ list of requested IDs that were invalid ],
  "ids": [ list of IDs that were valid ],
  "titles": [ list of valid product titles (corresponds with list of valid IDs) ],
  "descriptions": [ list of valid product descriptions ],
  "prices": [ list of valid product prices ],
  "localized_prices": [ list of valid product localized prices ],