plugins_for_ios.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. .. _doc_plugins_for_ios:
  2. Plugins for iOS
  3. ===============
  4. At the moment Godot provides StoreKit, GameCenter, iCloud services plugins.
  5. They are using same model of asynchronous calls explained below.
  6. ARKit and Camera access are also provided as plugins.
  7. Accessing plugin singletons
  8. ---------------------------
  9. To access plugin functionality, you first need to check that the plugin is
  10. exported and available by calling the `Engine.has_singleton()` function, which
  11. returns a registered singleton.
  12. Here's an example of how to do this in GDScript:
  13. ::
  14. var in_app_store
  15. func _ready():
  16. if Engine.has_singleton("InAppStore"):
  17. in_app_store = Engine.get_singleton("InAppStore")
  18. else:
  19. print("iOS IAP plugin is not exported.")
  20. Asynchronous methods
  21. --------------------
  22. When requesting an asynchronous operation, the method will look like
  23. this:
  24. ::
  25. Error purchase(Variant p_params);
  26. The parameter will usually be a Dictionary, with the information
  27. necessary to make the request, and the call will have two phases. First,
  28. the method will immediately return an Error value. If the Error is not
  29. 'OK', the call operation is completed, with an error probably caused
  30. locally (no internet connection, API incorrectly configured, etc). If
  31. the error value is 'OK', a response event will be produced and added to
  32. the 'pending events' queue. Example:
  33. ::
  34. func on_purchase_pressed():
  35. var result = in_app_store.purchase({ "product_id": "my_product" })
  36. if result == OK:
  37. animation.play("busy") # show the "waiting for response" animation
  38. else:
  39. show_error()
  40. # put this on a 1 second timer or something
  41. func check_events():
  42. while in_app_store.get_pending_event_count() > 0:
  43. var event = in_app_store.pop_pending_event()
  44. if event.type == "purchase":
  45. if event.result == "ok":
  46. show_success(event.product_id)
  47. else:
  48. show_error()
  49. Remember that when a call returns OK, the API will *always* produce an
  50. event through the pending_event interface, even if it's an error, or a
  51. network timeout, etc. You should be able to, for example, safely block
  52. the interface waiting for a reply from the server. If any of the APIs
  53. don't behave this way it should be treated as a bug.
  54. The pending event interface consists of two methods:
  55. - ``get_pending_event_count()``
  56. Returns the number of pending events on the queue.
  57. - ``Variant pop_pending_event()``
  58. Pops the first event from the queue and returns it.
  59. Store Kit
  60. ---------
  61. Implemented in `Godot iOS InAppStore plugin <https://github.com/godotengine/godot-ios-plugins/blob/master/plugins/inappstore/in_app_store.mm>`_.
  62. The Store Kit API is accessible through the ``InAppStore`` singleton.
  63. It is initialized automatically.
  64. - ``Error purchase(Variant p_params);``
  65. - ``Error request_product_info(Variant p_params);``
  66. - ``Error restore_purchases();``
  67. and the pending_event interface
  68. ::
  69. int get_pending_event_count();
  70. Variant pop_pending_event();
  71. purchase
  72. ~~~~~~~~
  73. Purchases a product id through the Store Kit API.
  74. Parameters
  75. ^^^^^^^^^^
  76. Takes a Dictionary as a parameter, with one field, ``product_id``, a
  77. string with your product id. Example:
  78. ::
  79. var result = InAppStore.purchase( { "product_id": "my_product" } )
  80. Response event
  81. ^^^^^^^^^^^^^^
  82. The response event will be a dictionary with the following fields:
  83. On error:
  84. ::
  85. {
  86. "type": "purchase",
  87. "result": "error",
  88. "product_id": "the product id requested"
  89. }
  90. On success:
  91. ::
  92. {
  93. "type": "purchase",
  94. "result": "ok",
  95. "product_id": "the product id requested"
  96. }
  97. request_product_info
  98. ~~~~~~~~~~~~~~~~~~~~
  99. Requests the product info on a list of product IDs.
  100. Parameters
  101. ^^^^^^^^^^
  102. Takes a Dictionary as a parameter, with one field, ``product_ids``, a
  103. string array with a list of product ids. Example:
  104. ::
  105. var result = InAppStore.request_product_info( { "product_ids": ["my_product1", "my_product2"] } )
  106. Response event
  107. ^^^^^^^^^^^^^^
  108. The response event will be a dictionary with the following fields:
  109. ::
  110. {
  111. "type": "product_info",
  112. "result": "ok",
  113. "invalid_ids": [ list of requested ids that were invalid ],
  114. "ids": [ list of ids that were valid ],
  115. "titles": [ list of valid product titles (corresponds with list of valid ids) ],
  116. "descriptions": [ list of valid product descriptions ] ,
  117. "prices": [ list of valid product prices ],
  118. "localized_prices": [ list of valid product localized prices ],
  119. }
  120. restore_purchases
  121. ~~~~~~~~~~~~~~~~~
  122. Restores previously made purchases on user's account. This will create
  123. response events for each previously purchased product id.
  124. Response event
  125. ^^^^^^^^^^^^^^
  126. The response events will be dictionaries with the following fields:
  127. ::
  128. {
  129. "type": "restore",
  130. "result": "ok",
  131. "product id": "product id of restored purchase"
  132. }
  133. Game Center
  134. -----------
  135. Implemented in `Godot iOS GameCenter plugin <https://github.com/godotengine/godot-ios-plugins/blob/master/plugins/gamecenter/game_center.mm>`_.
  136. The Game Center API is available through the ``GameCenter`` singleton. It
  137. has the following methods:
  138. - ``Error authenticate();``
  139. - ``bool is_authenticated();``
  140. - ``Error post_score(Variant p_score);``
  141. - ``Error award_achievement(Variant p_params);``
  142. - ``void reset_achievements();``
  143. - ``void request_achievements();``
  144. - ``void request_achievement_descriptions();``
  145. - ``Error show_game_center(Variant p_params);``
  146. - ``Error request_identity_verification_signature();``
  147. plus the standard pending event interface.
  148. authenticate
  149. ~~~~~~~~~~~~
  150. Authenticates a user in Game Center.
  151. Response event
  152. ^^^^^^^^^^^^^^
  153. The response event will be a dictionary with the following fields:
  154. On error:
  155. ::
  156. {
  157. "type": "authentication",
  158. "result": "error",
  159. "error_code": the value from NSError::code,
  160. "error_description": the value from NSError::localizedDescription,
  161. }
  162. On success:
  163. ::
  164. {
  165. "type": "authentication",
  166. "result": "ok",
  167. "player_id": the value from GKLocalPlayer::playerID,
  168. }
  169. post_score
  170. ~~~~~~~~~~
  171. Posts a score to a Game Center leaderboard.
  172. Parameters
  173. ^^^^^^^^^^
  174. Takes a Dictionary as a parameter, with two fields:
  175. - ``score`` a float number
  176. - ``category`` a string with the category name
  177. Example:
  178. ::
  179. var result = GameCenter.post_score( { "score": 100, "category": "my_leaderboard", } )
  180. Response event
  181. ^^^^^^^^^^^^^^
  182. The response event will be a dictionary with the following fields:
  183. On error:
  184. ::
  185. {
  186. "type": "post_score",
  187. "result": "error",
  188. "error_code": the value from NSError::code,
  189. "error_description": the value from NSError::localizedDescription,
  190. }
  191. On success:
  192. ::
  193. {
  194. "type": "post_score",
  195. "result": "ok",
  196. }
  197. award_achievement
  198. ~~~~~~~~~~~~~~~~~
  199. Modifies the progress of a Game Center achievement.
  200. Parameters
  201. ^^^^^^^^^^
  202. Takes a Dictionary as a parameter, with 3 fields:
  203. - ``name`` (string) the achievement name
  204. - ``progress`` (float) the achievement progress from 0.0 to 100.0
  205. (passed to ``GKAchievement::percentComplete``)
  206. - ``show_completion_banner`` (bool) whether Game Center should display
  207. an achievement banner at the top of the screen
  208. Example:
  209. ::
  210. var result = award_achievement( { "name": "hard_mode_completed", "progress": 6.1 } )
  211. Response event
  212. ^^^^^^^^^^^^^^
  213. The response event will be a dictionary with the following fields:
  214. On error:
  215. ::
  216. {
  217. "type": "award_achievement",
  218. "result": "error",
  219. "error_code": the error code taken from NSError::code,
  220. }
  221. On success:
  222. ::
  223. {
  224. "type": "award_achievement",
  225. "result": "ok",
  226. }
  227. reset_achievements
  228. ~~~~~~~~~~~~~~~~~~
  229. Clears all Game Center achievements. The function takes no parameters.
  230. Response event
  231. ^^^^^^^^^^^^^^
  232. The response event will be a dictionary with the following fields:
  233. On error:
  234. ::
  235. {
  236. "type": "reset_achievements",
  237. "result": "error",
  238. "error_code": the value from NSError::code
  239. }
  240. On success:
  241. ::
  242. {
  243. "type": "reset_achievements",
  244. "result": "ok",
  245. }
  246. request_achievements
  247. ~~~~~~~~~~~~~~~~~~~~
  248. Request all the Game Center achievements the player has made progress
  249. on. The function takes no parameters.
  250. Response event
  251. ^^^^^^^^^^^^^^
  252. The response event will be a dictionary with the following fields:
  253. On error:
  254. ::
  255. {
  256. "type": "achievements",
  257. "result": "error",
  258. "error_code": the value from NSError::code
  259. }
  260. On success:
  261. ::
  262. {
  263. "type": "achievements",
  264. "result": "ok",
  265. "names": [ list of the name of each achievement ],
  266. "progress": [ list of the progress made on each achievement ]
  267. }
  268. request_achievement_descriptions
  269. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  270. Request the descriptions of all existing Game Center achievements
  271. regardless of progress. The function takes no parameters.
  272. Response event
  273. ^^^^^^^^^^^^^^
  274. The response event will be a dictionary with the following fields:
  275. On error:
  276. ::
  277. {
  278. "type": "achievement_descriptions",
  279. "result": "error",
  280. "error_code": the value from NSError::code
  281. }
  282. On success:
  283. ::
  284. {
  285. "type": "achievement_descriptions",
  286. "result": "ok",
  287. "names": [ list of the name of each achievement ],
  288. "titles": [ list of the title of each achievement ]
  289. "unachieved_descriptions": [ list of the description of each achievement when it is unachieved ]
  290. "achieved_descriptions": [ list of the description of each achievement when it is achieved ]
  291. "maximum_points": [ list of the points earned by completing each achievement ]
  292. "hidden": [ list of booleans indicating whether each achievement is initially visible ]
  293. "replayable": [ list of booleans indicating whether each achievement can be earned more than once ]
  294. }
  295. show_game_center
  296. ~~~~~~~~~~~~~~~~
  297. Displays the built in Game Center overlay showing leaderboards,
  298. achievements, and challenges.
  299. Parameters
  300. ^^^^^^^^^^
  301. Takes a Dictionary as a parameter, with two fields:
  302. - ``view`` (string) (optional) the name of the view to present. Accepts
  303. "default", "leaderboards", "achievements", or "challenges". Defaults
  304. to "default".
  305. - ``leaderboard_name`` (string) (optional) the name of the leaderboard
  306. to present. Only used when "view" is "leaderboards" (or "default" is
  307. configured to show leaderboards). If not specified, Game Center will
  308. display the aggregate leaderboard.
  309. Examples:
  310. ::
  311. var result = show_game_center( { "view": "leaderboards", "leaderboard_name": "best_time_leaderboard" } )
  312. var result = show_game_center( { "view": "achievements" } )
  313. Response event
  314. ^^^^^^^^^^^^^^
  315. The response event will be a dictionary with the following fields:
  316. On close:
  317. ::
  318. {
  319. "type": "show_game_center",
  320. "result": "ok",
  321. }